if SERVER then
	AddCSLuaFile()

	resource.AddFile("materials/HUD/killicons/entityflame.vmt")
	resource.AddFile("materials/HUD/killicons/headshot.vmt")
	resource.AddFile("materials/HUD/killicons/player.vmt")
	resource.AddFile("materials/HUD/killicons/prop_ragdoll.vmt")
	resource.AddFile("materials/HUD/killicons/weapon_physcannon.vmt")

	resource.AddFile("sound/RagMod/Headshot.wav")
	resource.AddFile("sound/RagMod/Heartbeat.wav")
end

for HookType, Hook in pairs(hook.GetTable()) do
	for HookName, HookAction in pairs(Hook) do
		if string.sub(tostring(HookName), 1, 3) == "rm_" then
			hook.Remove(HookType, HookName)
			Msg("[RagMod] Removed " ..(CLIENT and "client" or (SERVER and "server" or "?")).. " hook " ..tostring(HookName).. ".\n")
		end
	end
end

_G.rm = rm or {}
rm.Version = "v5.72"
rm.CVarSwitches = {FCVAR_NOTIFY, FCVAR_REPLICATED}

rm.Enabled = CreateConVar("rm_enabled", 1, rm.CVarSwitches, "Enable RagMod 2 " ..rm.Version.. ".")
rm.EnabledDelta = rm.Enabled:GetBool()

rm.HintEnabled = CreateConVar("rm_hint_enabled", 1, rm.CVarSwitches, "Enable client hints.")
rm.HintTime = CreateClientConVar("rm_hint_time", 3, false, false)

rm.SoundEnabled = CreateConVar("rm_sound_enabled", 1, rm.CVarSwitches, "Enable sounds.")
rm.SoundVolume = CreateConVar("rm_sound_volume", 80, rm.CVarSwitches, "The global volume of all RagMod sounds (0 to 100).")
rm.SoundDelay = CreateConVar("rm_sound_delay", 0.75, rm.CVarSwitches, "The delay (in seconds) before sounds can be played again (to avoid clipping).")

rm.OxygenEnabled = CreateConVar("rm_oxygen_enabled", 1, rm.CVarSwitches, "Enable oxygen while underwater.")
rm.OxygenValue = CreateConVar("rm_oxygen_value", 30, rm.CVarSwitches, "The amount (in seconds) of oxygen a player has.")
rm.OxygenRegenerateValue = CreateConVar("rm_oxygen_regenerate_value", 2.5, rm.CVarSwitches, "The multiplier a player will regenerate oxygen at (ex. a player can regenerate oxygen this number of times faster than the speed at which it is lost).")
rm.OxygenDrownValue = CreateConVar("rm_oxygen_drown_value", 5, rm.CVarSwitches, "Every one in this number of ticks a player will lose health while drowning.")
rm.OxygenHUDEnabled = CreateClientConVar("rm_oxygen_hud_enabled", 1, true, false)
rm.OxygenHUDTextEnabled = CreateClientConVar("rm_oxygen_hud_text_enabled", 1, true, false)
rm.OxygenHUDBarEnabled = CreateClientConVar("rm_oxygen_hud_bar_enabled", 1, true, false)

rm.AfterdeathEnabled = CreateConVar("rm_afterdeath_enabled", 1, rm.CVarSwitches, "Enable Afterdeath.")
rm.AfterdeathClientEnabled = CreateClientConVar("rm_afterdeath_client_enabled", 1, true, false)
rm.AfterdeathHUDEnabled = CreateClientConVar("rm_afterdeath_hud_enabled", 1, true, false)
rm.AfterdeathHUDKillerEnabled = CreateClientConVar("rm_afterdeath_hud_killer_enabled", 1, true, false)
rm.AfterdeathHUDKillsEnabled = CreateClientConVar("rm_afterdeath_hud_kills_enabled", 1, true, false)
rm.AfterdeathHUDRespawnTimeEnabled = CreateClientConVar("rm_afterdeath_hud_respawntime_enabled", 1, true, false)
rm.AfterdeathCameraMode = CreateClientConVar("rm_afterdeath_camera_mode", 2, true, false)

rm.HeadshotEnabled = CreateConVar("rm_headshot_enabled", 1, rm.CVarSwitches, "Enable headshot detection.")
rm.HeadshotClientEnabled = CreateClientConVar("rm_headshot_client_enabled", 1, true, false)
rm.HeadshotSoundEnabled = CreateClientConVar("rm_headshot_sound_enabled", 1, true, false)

rm.RespawnDelay = CreateConVar("rm_respawn_delay", 3, rm.CVarSwitches, "The number of seconds a player must wait before respawning.")

rm.NinjaModeEnabled = CreateConVar("rm_ninjamode_enabled", 0, rm.CVarSwitches, "This console variable has no use. I do not recommend modifying it in any way, shape, or form; doing so may void your warranty.")

rm.RagdollRecoveryEnabled = CreateConVar("rm_ragdoll_recovery_enabled", 1, rm.CVarSwitches, "Enable recovery from ragdolization (to remove the timer, see rm_ragdoll_recovery_timer_enabled).")
rm.RagdollRecoverySmoothingEnabled = CreateConVar("rm_ragdoll_recovery_smoothing_enabled", 1, rm.CVarSwitches, "Enable recovery smoothing.")
rm.RagdollRecoveryDelayEnabled = CreateConVar("rm_ragdoll_recovery_delay_enabled", 1, rm.CVarSwitches, "Enable the recovery delay timer (if disabled, players can recover immediately).")
rm.RagdollRecoveryDelayOnExplosion = CreateConVar("rm_ragdoll_recovery_delay_onexplosion", 10, rm.CVarSwitches, "The number of seconds a player must wait before getting back up when when ragdolzied by being caught in an explosion.")
rm.RagdollRecoveryDelayOnEject = CreateConVar("rm_ragdoll_recovery_delay_oneject", 7, rm.CVarSwitches, "The number of seconds a player must wait before getting back up when ragdolzied by ejecting from a seat.")
rm.RagdollRecoveryDelayOnFall = CreateConVar("rm_ragdoll_recovery_delay_onfall", 8, rm.CVarSwitches, "The number of seconds a player must wait before getting back up when ragdolzied by taking fall damage or when going faster than a certain value.")
rm.RagdollRecoveryDelayOnPlayer = CreateConVar("rm_ragdoll_recovery_delay_onplayer", 5, rm.CVarSwitches, "The number of seconds a player must wait before getting back up when ragdolzied by taking damage from a player or NPC.")
rm.RagdollRecoveryDelayDefault = CreateConVar("rm_ragdoll_recovery_delay_default", 3, rm.CVarSwitches, "The number of seconds a player must wait before getting back up when ragdolized from other sources.")
rm.RagdollRecoveryHUDEnabled = CreateClientConVar("rm_ragdoll_recovery_hud_enabled", 1, true, false)
rm.RagdollRecoveryWeaponPreserveEnabled = CreateConVar("rm_ragdoll_recovery_weapon_preserve_enabled", 1, rm.CVarSwitches, "Enable the preservation of weapons when recovering.")

rm.WeaponDropOnRagdollEnabled = CreateConVar("rm_weapon_drop_onragdoll_enabled", 1, rm.CVarSwitches, "Enable equipped weapons dropping upon ragdolization.")
rm.WeaponDropOnDeathEnabled = CreateConVar("rm_weapon_drop_ondeath_enabled", 1, rm.CVarSwitches, "Enable equipped weapons dropping upon death.")
rm.WeaponDropOnDrownEnabled = CreateConVar("rm_weapon_drop_ondrown_enabled", 1, rm.CVarSwitches, "Enable equipped weapons dropping upon drowning.")
rm.WeaponDropOnSuicideEnabled = CreateConVar("rm_weapon_drop_onsuicide_enabled", 1, rm.CVarSwitches, "Enable equipped weapons dropping upon suicide.")
rm.WeaponCrossbowWeldEnabled = CreateConVar("rm_weapon_crossbow_weld_enabled", 1, rm.CVarSwitches, "Enable RagMod ragdolls being welded to objects when shot with the Crossbow.")

rm.RagdollResetEnabled = CreateConVar("rm_ragdoll_reset_enabled", 1, rm.CVarSwitches, "Enable resetting while ragdolzied.")

rm.RagdollBloodEnabled = CreateConVar("rm_ragdoll_blood_enabled", 1, rm.CVarSwitches, "Enable RagMod ragdoll blood.")
rm.RagdollBloodSpurtEnabled = CreateClientConVar("rm_ragdoll_blood_spurt_enabled", 1, true, false)
rm.RagdollBloodSpurtStyle = CreateClientConVar("rm_ragdoll_blood_spurt_style", 2, true, false)
rm.RagdollDecapitationEnabled = CreateConVar("rm_ragdoll_decapitation_enabled", 1, rm.CVarSwitches, "Enable RagMod ragdoll decapitation.")
rm.RagdollDecapitationValue = CreateConVar("rm_ragdoll_decapitation_value", 30, rm.CVarSwitches, "The damage required to decapitate.")
rm.RagdollGibEnabled = CreateConVar("rm_ragdoll_gib_enabled", 1, rm.CVarSwitches, "Enable RagMod ragdoll gibbing.")
rm.RagdollGibValue = CreateConVar("rm_ragdoll_gib_value", 50, rm.CVarSwitches, "The damage required to gib.")
rm.RagdollGibEffectEnabled = CreateClientConVar("rm_ragdoll_gib_effect_enabled", 1, true, false)
rm.RagdollGibEffectMultiplier = CreateClientConVar("rm_ragdoll_gib_effect_multiplier", 1, true, false)

rm.RagdollKeepEnabled = CreateConVar("rm_ragdoll_keep_enabled", 1, rm.CVarSwitches, "Enable the preservation of dead RagMod ragdolls. If disabled, NPC ragdolls will disappear after a minute.")
rm.RagdollKeepPlayerValue = CreateConVar("rm_ragdoll_keep_player_value", 2, rm.CVarSwitches, "The number of ragdolls to keep per-player (0 is infinite).")
rm.RagdollKeepNPCValue = CreateConVar("rm_ragdoll_keep_npc_value", 3, rm.CVarSwitches, "The number of ragdolls to keep for NPCs (0 is infinite).")

rm.RagdollDamageEnabled = CreateConVar("rm_ragdoll_damage_enabled", 1, rm.CVarSwitches, "Enable the damaging of RagMod ragdolls (This does not influence other damage-related effects).")
rm.RagdollDamagePVPEnabled = CreateConVar("rm_ragdoll_damage_pvp_enabled", 1, rm.CVarSwitches, "Enable players to damage other players' RagMod ragdolls")
rm.RagdollDamageMultiplier = CreateConVar("rm_ragdoll_damage_multiplier", 1, rm.CVarSwitches, "The multiplier at which a player will take damage while ragdolized.")
rm.RagdollDamageFixInfoEnabled = CreateConVar("rm_ragdoll_damage_fixinfo_enabled", 1, rm.CVarSwitches, [[Enable the repair of damage information:
    When a player dies as a RagMod ragdoll, it is technically commiting suicide; the killer and inflictor will be replaced accordingly.
    If the attacker is also the inflictor or the inflictor is not valid, the inflictor is replaced with the attacker's weapon, even if it is not used. If the inflictor is still not valid, the world will be used instead (as if the player was killed with a world prop).
	(Note: This is a feature in some cases and a bug in others; should the need arise, this may be removed)]])

rm.RagdollBounceEnabled = CreateConVar("rm_ragdoll_bounce_enabled", 1, rm.CVarSwitches, "Enable an enhanced RagMod ragdoll bounce effect.")
rm.RagdollBounceMultiplier = CreateConVar("rm_ragdoll_bounce_multiplier", 1, rm.CVarSwitches, "The force multiplier that RagMod ragdolls bounce at.")

rm.RagdollForceType = CreateConVar("rm_ragdoll_force_type", 2, rm.CVarSwitches, "The way force to RagMod ragdolls is handled.\n1: Standard force from damage information.\n2: RagMod normalized damage-based force.")
rm.RagdollForceMultiplier = CreateConVar("rm_ragdoll_force_multiplier", 1, rm.CVarSwitches, "The force multiplier that damage pushes RagMod ragdolls.")
rm.RagdollForceMultiplierExplosion = CreateConVar("rm_ragdoll_force_multiplier_explosion", 1, rm.CVarSwitches, "The force multiplier that explosions push RagMod ragdolls.")

rm.RagdollBurnEnabled = CreateConVar("rm_ragdoll_burn_enabled", 1, rm.CVarSwitches, "Enable burning effects on RagMod ragdolls.")
rm.RagdollBurnOnExplosionEnabled = CreateConVar("rm_ragdoll_burn_onexplosion_enabled", 1, rm.CVarSwitches, "Enable the ability to catch a RagMod ragdoll on fire when caught in explosions.")
rm.RagdollBurnOnExplosionValue = CreateConVar("rm_ragdoll_burn_onexplosion_value", 10, rm.CVarSwitches, "RagMod ragdolls will catch on fire when caught in explosions every one in this number of times.")
rm.RagdollBurnDeflateEnabled = CreateClientConVar("rm_ragdoll_burn_deflate_enabled", 1, rm.CVarSwitches, true, false)
rm.RagdollBurnDeflateData =
{
	"ValveBiped.Bip01_Head1",		0.95,
	"ValveBiped.Bip01_Spine4",		0.97,
	"ValveBiped.Bip01_Spine",		0.2,
	"ValveBiped.Bip01_L_UpperArm",	0.7,
	"ValveBiped.Bip01_R_UpperArm",	0.7,
	"ValveBiped.Bip01_Spine2",		0.8,
	"ValveBiped.Bip01_L_Forearm",	0.6,
	"ValveBiped.Bip01_R_Forearm",	0.6,
	"ValveBiped.Bip01_Pelvis",		0.9,
	"ValveBiped.Bip01_L_Hand",		0.8,
	"ValveBiped.Bip01_R_Hand",		0.8,
	"ValveBiped.Bip01_L_Thigh",		0.6,
	"ValveBiped.Bip01_R_Thigh",		0.6,
	"ValveBiped.Bip01_L_Calf",		0.6,
	"ValveBiped.Bip01_R_Calf",		0.6,
}

rm.RagdollMoveEnabled = CreateConVar("rm_ragdoll_move_enabled", 1, rm.CVarSwitches, "Enable various RagMod ragdoll movements activated with the forward key: crawling, swimming, gliding, etc.")
rm.RagdollMoveSupermanModeEnabled = CreateConVar("rm_ragdoll_move_supermanmode_enabled", 0, rm.CVarSwitches, "This console variable has no use. I do not recommend modifying it in any way, shape, or form; doing so may void your warranty.")

rm.RagdollTwitchEnabled = CreateConVar("rm_ragdoll_twitch_enabled", 1, rm.CVarSwitches, "Enable RagMod ragdoll randomized twitching.")
rm.RagdollTwitchOnCommandEnabled = CreateConVar("rm_ragdoll_twitch_oncommand_enabled", 1, rm.CVarSwitches, "Enable RagMod ragdoll twitching activated by holding the back key.")
rm.RagdollTwitchOnDamageEnabled = CreateConVar("rm_ragdoll_twitch_ondamage_enabled", 1, rm.CVarSwitches, "Enable RagMod ragdoll twitching when damaged.")
rm.RagdollTwitchOnDamageMultiplier = CreateConVar("rm_ragdoll_twitch_ondamage_multiplier", 1, rm.CVarSwitches, "The multiplier at which RagMod ragdolls will twitch based on the damage taken.")
rm.RagdollTwitchOnSpeedEnabled = CreateConVar("rm_ragdoll_twitch_onspeed_enabled", 1, rm.CVarSwitches, "Enable RagMod ragdoll twitching based on their velocity.")
rm.RagdollTwitchOnSpeedMultiplier = CreateConVar("rm_ragdoll_twitch_onspeed_multiplier", 1, rm.CVarSwitches, "The multiplier at which RagMod ragdolls will twitch based on their velocity.")
rm.RagdollTwitchOnDeathEnabled = CreateConVar("rm_ragdoll_twitch_ondeath_enabled", 1, rm.CVarSwitches, "Enable RagMod ragdoll twitching while dead.")

rm.RagdollGrabEnabled = CreateConVar("rm_ragdoll_grab_enabled", 1, rm.CVarSwitches, "Enable the ability to grab onto props.")
rm.RagdollGrabOnCommandEnabled = CreateConVar("rm_ragdoll_grab_oncommand_enabled", 1, rm.CVarSwitches, "Enable the ability to grab onto props on command.")
rm.RagdollGrabStrength = CreateConVar("rm_ragdoll_grab_strength", 9500, rm.CVarSwitches, "The strength at which the grabbing RagMod ragdoll holds on.")

rm.RagdollParachuteEnabled = CreateConVar("rm_ragdoll_parachute_enabled", 1, rm.CVarSwitches, "Enable RagMod ragdoll parachutes.")
rm.RagdollParachuteOnCommandEnabled = CreateConVar("rm_ragdoll_parachute_oncommand_enabled", 1, rm.CVarSwitches, "Enable RagMod ragdoll parachutes.")
rm.RagdollParachuteOnCommandUnlimitedEnabled = CreateConVar("rm_ragdoll_parachute_oncommand_unlimited_enabled", 0, rm.CVarSwitches, "Enable unlimited RagMod ragdoll parachutes.")
rm.RagdollParachuteMultiplier = CreateConVar("rm_ragdoll_parachute_multiplier", 1, rm.CVarSwitches, "The parachute damping multiplier.")

rm.RagdollDeathEffectEnabled = CreateConVar("rm_ragdoll_death_effect_enabled", 1, rm.CVarSwitches, "Enable a slowed fall when killing players and NPCs with low damage (note that the respective ragdolizing functionalities must be enabled).")
rm.RagdollDeathEffectMultiplier = CreateConVar("rm_ragdoll_death_effect_multiplier", 1, rm.CVarSwitches, "The damping multiplier (note that there isn't much of a change with higher values because only one bone is affected).")
rm.RagdollDeathFacePoseEnabled = CreateConVar("rm_ragdoll_death_facepose_enabled", 1, rm.CVarSwitches, "Pose the face flexes when dying.")

rm.RagdollToolGunEnabled = CreateConVar("rm_ragdoll_toolgun_enabled", 0, rm.CVarSwitches, "Enable the ability to use the ToolGun on RagMod ragdolls (does not apply to non-player RagMod ragdolls).")
rm.RagdollPhysGunEnabled = CreateConVar("rm_ragdoll_physgun_enabled", 0, rm.CVarSwitches, "Enable the ability to use the PhysGun on players and RagMod ragdolls (does not apply to non-player RagMod ragdolls).")

rm.RagdolizeOnCommandEnabled = CreateConVar("rm_ragdolize_oncommand_enabled", 1, rm.CVarSwitches, "Enable the ability to ragdolize on command.")
rm.RagdolizeOnFallEnabled = CreateConVar("rm_ragdolize_onfall_enabled", 1, rm.CVarSwitches, "Enable the ragdolizing of players when taking any fall damage.")
rm.RagdolizeOnDamageEnabled = CreateConVar("rm_ragdolize_ondamage_enabled", 1, rm.CVarSwitches, "Enable the ragdolizing of players when taking an amount of damage.")
rm.RagdolizeOnDamageValue = CreateConVar("rm_ragdolize_ondamage_value", 35, rm.CVarSwitches, "The amount of damage needed to ragdolize players.")
rm.RagdolizeOnDamageVehicleValue = CreateConVar("rm_ragdolize_ondamage_vehicle_value", 10, rm.CVarSwitches, "The amount of damage needed to ragdolize players when inside vehicles.")
rm.RagdolizeOnSpeedEnabled = CreateConVar("rm_ragdolize_onspeed_enabled", 1, rm.CVarSwitches, "Enable the ragdolizing of players when going faster than a certain value.")
rm.RagdolizeOnSpeedValue = CreateConVar("rm_ragdolize_onspeed_value", 1501, rm.CVarSwitches, "The amount of speed needed to ragdolize players.")
rm.RagdolizeOnEjectEnabled = CreateConVar("rm_ragdolize_oneject_enabled", 1, rm.CVarSwitches, "Enable the ragdolizing of players when ejecting from a seat.")
rm.RagdolizeOnEjectValue = CreateConVar("rm_ragdolize_oneject_value", 100, rm.CVarSwitches, "The amount of speed when ejecting players need to ragdolize.")
rm.RagdolizeOnDeathEnabled = CreateConVar("rm_ragdolize_ondeath_enabled", 1, rm.CVarSwitches, "Enable the ragdolizing of players upon death.")

rm.NPCRagdolizeBlacklist = CreateConVar("rm_npc_ragdolize_blacklist", "C_AI_BaseNPC,crow,pigeon,seagull,cscanner,clawscanner,manhack,rollermine,turret,turret_floor,bigmomma,cockroach,gargantua,nihilanth,snark,tentacle,dog,antlionguard,barnacle,strider,fisherman", rm.CVarSwitches, "Any NPC class names (\"npc_\" and \"monster_\" prefixes optional) in this list, separated by a comma, will not be ragdolized.")
rm.NPCRagdolizeOnDeathEnabled = CreateConVar("rm_npc_ragdolize_ondeath_enabled", 1, rm.CVarSwitches, "Enable the ragdolizing of NPCs upon death. ai_serverragdolls will be set to 1 for compatibility reasons.")

rm.RagdollCameraMode = CreateClientConVar("rm_ragdoll_camera_mode", 0, true, false)

rm.PPEnabled = CreateClientConVar("rm_pp_enabled", 1, true, false)
rm.PPRestrict = CreateClientConVar("rm_pp_restrict", 0, true, false)
rm.PPAddR = CreateClientConVar("rm_pp_addr", 0, true, false)
rm.PPAddG = CreateClientConVar("rm_pp_addg", 0, true, false)
rm.PPAddB = CreateClientConVar("rm_pp_addb", 0, true, false)
rm.PPBrightness = CreateClientConVar("rm_pp_brightness", 0.9, true, false)
rm.PPContrast = CreateClientConVar("rm_pp_contrast", 1.3, true, false)
rm.PPColor = CreateClientConVar("rm_pp_color", 0.4, true, false)
rm.PPMulR = CreateClientConVar("rm_pp_mulr", 1, true, false)
rm.PPMulG = CreateClientConVar("rm_pp_mulg", 1, true, false)
rm.PPMulB = CreateClientConVar("rm_pp_mulb", 1, true, false)
rm.PPBlurAlpha = CreateClientConVar("rm_pp_bluralpha", 0.7, true, false)

rm.PPMotionBlurEnabled = CreateClientConVar("rm_pp_motionblur_enabled", 1, true, false)
rm.PPMotionBlurRestrict = CreateClientConVar("rm_pp_motionblur_restrict", 0, true, false)
rm.PPMotionBlurScale = CreateClientConVar("rm_pp_motionblur_scale", 1, true, false)

rm.SoundHeartbeatEnabled = CreateClientConVar("rm_sound_heartbeat_enabled", 1, true, false)
rm.SoundWindEnabled = CreateClientConVar("rm_sound_wind_enabled", 1, true, false)
rm.SoundWindRestrict = CreateClientConVar("rm_sound_wind_restrict", 0, true, false)

rm.Genders =
{
	Alyx = {"player/alyx%.mdl"},
	Breen = {"player/breen%.mdl"},
	Barney = {"player/barney%.mdl"},
	GMan = {"player/gman_high%.mdl"},
	Kleiner = {"player/kleiner%.mdl"},
	Mossman = {"player/mossman%.mdl"},
	Odessa = {"player/odessa%.mdl"},

	CombineMetropolice =
	{
		"player/police%.mdl",
		"gasmask",
		"gas_mask"
	},
	CombineSoldier =
	{
		"combine",
		"soldier_stripped"
	},
	Female =
	{
		"female",
		"girl",
		"woman"
	},
	Zombie =
	{
		"charple",
		"corpse",
		"player/classic%.mdl",
		"zombie"
	}
}
rm.Sounds =
{
	FleshSquish =
	{
		Sound("ambient/levels/canals/toxic_slime_gurgle2.wav"),
		Sound("ambient/levels/canals/toxic_slime_gurgle4.wav"),
		Sound("ambient/levels/canals/toxic_slime_gurgle8.wav"),
		Sound("physics/flesh/flesh_bloody_impact_hard1.wav"),
		Sound("physics/flesh/flesh_squishy_impact_hard2.wav"),
		Sound("physics/flesh/flesh_squishy_impact_hard3.wav"),
		Sound("physics/flesh/flesh_squishy_impact_hard4.wav")
	},
	FleshBreak =
	{
		Sound("npc/barnacle/barnacle_crunch2.wav"),
		Sound("npc/barnacle/barnacle_crunch3.wav"),
		Sound("npc/barnacle/neck_snap1.wav"),
		Sound("npc/barnacle/neck_snap2.wav"),
		Sound("physics/flesh/flesh_bloody_break.wav"),
		Sound("physics/flesh/flesh_squishy_impact_hard1.wav")
	},
	PlayerDrown =
	{
		Sound("player/pl_drown1.wav"),
		Sound("player/pl_drown2.wav"),
		Sound("player/pl_drown3.wav")
	},
	PlayerBurn =
	{
		Sound("player/pl_burnpain1.wav"),
		Sound("player/pl_burnpain2.wav"),
		Sound("player/pl_burnpain3.wav")
	},
	AlyxFreeFall =
	{
		Sound("vo/NovaProspekt/al_uhoh_np.wav"),
		Sound("vo/npc/Alyx/lookout01.wav"),
		Sound("vo/npc/Alyx/lookout03.wav"),
		Sound("vo/npc/Alyx/ohno_startle01.wav"),
		Sound("vo/npc/Alyx/ohno_startle03.wav"),
		Sound("vo/npc/Alyx/watchout01.wav"),
		Sound("vo/npc/Alyx/watchout02.wav"),
		Sound("vo/Streetwar/Alyx_gate/al_ahno.wav")
	},
	AlyxPain =
	{
		Sound("vo/Citadel/al_dienow.wav"),
		Sound("vo/Citadel/al_struggle07.wav"),
		Sound("vo/Citadel/al_struggle08.wav"),
		Sound("vo/eli_lab/al_dogairlock01.wav"),
		Sound("vo/NovaProspekt/al_combinespy01.wav"),
		Sound("vo/NovaProspekt/al_gasp01.wav"),
		Sound("vo/npc/Alyx/gasp02.wav"),
		Sound("vo/npc/Alyx/gasp03.wav"),
		Sound("vo/npc/Alyx/hurt04.wav"),
		Sound("vo/npc/Alyx/hurt05.wav"),
		Sound("vo/npc/Alyx/hurt06.wav"),
		Sound("vo/npc/Alyx/hurt08.wav"),
		Sound("vo/npc/Alyx/uggh01.wav"),
		Sound("vo/npc/Alyx/uggh02.wav"),
		Sound("vo/Streetwar/Alyx_gate/al_ah.wav")
	},
	AlyxDeath =
	{
		Sound("vo/Citadel/al_dadgordonno_c.wav"),
		Sound("vo/Citadel/al_dadsorry.wav"),
		Sound("vo/Citadel/al_struggle01.wav"),
		Sound("vo/Citadel/al_struggle02.wav"),
		Sound("vo/Citadel/al_struggle03.wav"),
		Sound("vo/Citadel/al_struggle05.wav"),
		Sound("vo/NovaProspekt/al_gordon01.wav"),
		Sound("vo/NovaProspekt/al_horrible01.wav"),
		Sound("vo/NovaProspekt/al_ohmygod.wav"),
		Sound("vo/npc/Alyx/gordon_dist01.wav"),
		Sound("vo/npc/Alyx/no01.wav"),
		Sound("vo/npc/Alyx/no02.wav"),
		Sound("vo/npc/Alyx/no03.wav"),
		Sound("vo/npc/Alyx/ohgod01.wav"),
		Sound("vo/Streetwar/Alyx_gate/al_no.wav")
	},
	BreenFreeFall =
	{
		Sound("vo/Citadel/br_failing11.wav"),
		Sound("vo/Citadel/br_no.wav"),
		Sound("vo/Citadel/br_ohshit.wav"),
		Sound("vo/npc/male01/pain01.wav"),
		Sound("vo/npc/male01/startle01.wav"),
		Sound("vo/npc/male01/startle02.wav")
	},
	BreenPain =
	{
		Sound("vo/Citadel/br_failing11.wav"),
		Sound("vo/Citadel/br_no.wav"),
		Sound("vo/Citadel/br_ohshit.wav"),
		Sound("vo/npc/male01/pain01.wav"),
		Sound("vo/npc/male01/startle01.wav"),
		Sound("vo/npc/male01/startle02.wav")
	},
	BreenDeath =
	{
		Sound("vo/Citadel/br_failing11.wav"),
		Sound("vo/Citadel/br_laugh01.wav"),
		Sound("vo/Citadel/br_no.wav"),
		Sound("vo/Citadel/br_ohshit.wav"),
		Sound("vo/Citadel/br_youfool.wav"),
		Sound("vo/Citadel/br_youneedme.wav"),
		Sound("vo/npc/male01/pain01.wav"),
		Sound("vo/npc/male01/startle01.wav"),
		Sound("vo/npc/male01/startle02.wav")
	},
	BarneyFreeFall =
	{
		Sound("vo/k_lab/ba_cantlook.wav"),
		Sound("vo/k_lab/ba_whatthehell.wav"),
		Sound("vo/k_lab2/ba_incoming.wav"),
		Sound("vo/npc/Barney/ba_damnit.wav"),
		Sound("vo/npc/Barney/ba_duck.wav"),
		Sound("vo/npc/Barney/ba_getdown.wav"),
		Sound("vo/npc/Barney/ba_getoutofway.wav"),
		Sound("vo/npc/Barney/ba_hereitcomes.wav"),
		Sound("vo/npc/Barney/ba_lookout.wav")
	},
	BarneyPain =
	{
		Sound("vo/k_lab/ba_getitoff01.wav"),
		Sound("vo/k_lab/ba_thingaway02.wav"),
		Sound("vo/npc/Barney/ba_pain01.wav"),
		Sound("vo/npc/Barney/ba_pain02.wav"),
		Sound("vo/npc/Barney/ba_pain03.wav"),
		Sound("vo/npc/Barney/ba_pain04.wav"),
		Sound("vo/npc/Barney/ba_pain05.wav"),
		Sound("vo/npc/Barney/ba_pain06.wav"),
		Sound("vo/npc/Barney/ba_pain07.wav"),
		Sound("vo/npc/Barney/ba_pain08.wav"),
		Sound("vo/npc/Barney/ba_pain09.wav"),
		Sound("vo/npc/Barney/ba_pain10.wav")
	},
	BarneyDeath =
	{
		Sound("vo/k_lab/ba_guh.wav"),
		Sound("vo/k_lab/ba_thingaway02.wav"),
		Sound("vo/npc/Barney/ba_no01.wav"),
		Sound("vo/npc/Barney/ba_no02.wav"),
		Sound("vo/npc/Barney/ba_ohshit03.wav"),
		Sound("vo/Streetwar/rubble/ba_damnitall.wav")
	},
	GManFreeFall =
	{
		Sound("vo/npc/male01/startle01.wav")
	},
	GManDeath =
	{
		Sound("vo/Citadel/gman_exit01.wav"),
		Sound("vo/Citadel/gman_exit02.wav"),
		Sound("vo/Citadel/gman_exit10.wav")
	},
	KleinerFreeFall =
	{
		Sound("vo/k_lab/kl_ahhhh.wav"),
		Sound("vo/k_lab/kl_dearme.wav"),
		Sound("vo/k_lab/kl_fiddlesticks.wav"),
		Sound("vo/k_lab/kl_getoutrun02.wav"),
		Sound("vo/k_lab/kl_getoutrun03.wav"),
		Sound("vo/k_lab/kl_hedyno03.wav"),
		Sound("vo/k_lab/kl_ohdear.wav"),
		Sound("vo/k_lab2/kl_notallhopeless_b.wav"),
		Sound("vo/trainyard/kl_morewarn01.wav")
	},
	KleinerPain =
	{
		Sound("vo/k_lab/kl_ahhhh.wav"),
		Sound("vo/k_lab/kl_hedyno03.wav"),
		Sound("vo/npc/male01/pain01.wav"),
		Sound("vo/npc/male01/startle01.wav"),
		Sound("vo/npc/male01/startle02.wav")
	},
	KleinerDeath =
	{
		Sound("vo/k_lab/kl_ahhhh.wav"),
		Sound("vo/k_lab/kl_dearme.wav"),
		Sound("vo/k_lab/kl_hedyno03.wav"),
		Sound("vo/k_lab/kl_ohdear.wav"),
		Sound("vo/k_lab2/kl_greatscott.wav"),
		Sound("vo/trainyard/kl_morewarn01.wav")
	},
	MossmanFreeFall =
	{
		Sound("vo/eli_lab/mo_hereseli01.wav"),
		Sound("vo/npc/female01/pain02.wav"),
		Sound("vo/npc/female01/startle01.wav"),
		Sound("vo/npc/female01/startle02.wav")
	},
	MossmanPain =
	{
		Sound("vo/eli_lab/mo_hereseli01.wav"),
		Sound("vo/npc/female01/pain02.wav"),
		Sound("vo/npc/female01/startle01.wav"),
		Sound("vo/npc/female01/startle02.wav")
	},
	MossmanDeath =
	{
		Sound("vo/Citadel/mo_sorrygordon.wav"),
		Sound("vo/eli_lab/mo_hereseli01.wav"),
		Sound("vo/npc/female01/moan01.wav"),
		Sound("vo/npc/female01/moan02.wav"),
		Sound("vo/npc/female01/moan03.wav"),
		Sound("vo/npc/female01/moan04.wav"),
		Sound("vo/npc/female01/moan05.wav"),
		Sound("vo/npc/female01/pain02.wav"),
		Sound("vo/npc/female01/startle01.wav"),
		Sound("vo/npc/female01/startle02.wav")
	},
	OdessaFreeFall =
	{
		Sound("vo/npc/male01/pain01.wav")
	},
	OdessaPain =
	{
		Sound("vo/npc/male01/pain02.wav"),
		Sound("vo/npc/male01/pain03.wav"),
		Sound("vo/npc/male01/pain04.wav"),
		Sound("vo/npc/male01/pain05.wav"),
		Sound("vo/npc/male01/pain06.wav")
	},
	OdessaDeath =
	{
		Sound("vo/coast/odessa/nlo_cub_thatsthat.wav"),
		Sound("vo/npc/male01/moan01.wav"),
		Sound("vo/npc/male01/moan02.wav"),
		Sound("vo/npc/male01/moan03.wav"),
		Sound("vo/npc/male01/moan04.wav"),
		Sound("vo/npc/male01/moan05.wav")
	},

	CombineMetropoliceFreeFall =
	{
		Sound("npc/metropolice/vo/help.wav"),
		Sound("npc/metropolice/vo/lookout.wav"),
		Sound("npc/metropolice/vo/moveit.wav"),
		Sound("npc/metropolice/vo/shit.wav"),
		Sound("npc/metropolice/vo/takecover.wav"),
		Sound("npc/metropolice/vo/watchit.wav")
	},
	CombineMetropolicePain =
	{
		Sound("npc/metropolice/pain1.wav"),
		Sound("npc/metropolice/pain2.wav"),
		Sound("npc/metropolice/pain3.wav"),
		Sound("npc/metropolice/pain4.wav"),
		Sound("npc/metropolice/vo/chuckle.wav"),
		Sound("npc/metropolice/vo/shit.wav")
	},
	CombineMetropoliceDeath =
	{
		Sound("npc/metropolice/die1.wav"),
		Sound("npc/metropolice/die2.wav"),
		Sound("npc/metropolice/die3.wav")
	},
	CombineSoldierFreeFall =
	{
		Sound("npc/combine_soldier/vo/inbound.wav"),
		Sound("npc/combine_soldier/vo/coverhurt.wav")
	},
	CombineSoldierPain =
	{
		Sound("npc/combine_soldier/pain1.wav"),
		Sound("npc/combine_soldier/pain2.wav"),
		Sound("npc/combine_soldier/pain3.wav"),
	},
	CombineSoldierDeath =
	{
		Sound("npc/combine_soldier/die1.wav"),
		Sound("npc/combine_soldier/die2.wav"),
		Sound("npc/combine_soldier/die3.wav")
	},
	FemaleFreeFall =
	{
		Sound("vo/canals/female01/stn6_incoming.wav"),
		Sound("vo/npc/female01/headsup02.wav"),
		Sound("vo/npc/female01/help01.wav"),
		Sound("vo/npc/female01/incoming02.wav"),
		Sound("vo/npc/female01/runforyourlife01.wav"),
		Sound("vo/npc/female01/runforyourlife02.wav"),
		Sound("vo/npc/female01/uhoh.wav"),
		Sound("vo/npc/female01/watchout.wav")
	},
	FemalePain =
	{
		Sound("vo/npc/female01/imhurt01.wav"),
		Sound("vo/npc/female01/imhurt02.wav"),
		Sound("vo/npc/female01/ow01.wav"),
		Sound("vo/npc/female01/ow02.wav"),
		Sound("vo/npc/female01/pain01.wav"),
		Sound("vo/npc/female01/pain02.wav"),
		Sound("vo/npc/female01/pain03.wav"),
		Sound("vo/npc/female01/pain04.wav"),
		Sound("vo/npc/female01/pain05.wav"),
		Sound("vo/npc/female01/pain06.wav"),
		Sound("vo/npc/female01/pain07.wav"),
		Sound("vo/npc/female01/pain08.wav"),
		Sound("vo/npc/female01/pain09.wav"),
		Sound("vo/npc/female01/startle01.wav"),
		Sound("vo/npc/female01/startle02.wav")
	},
	FemaleDeath =
	{
		Sound("vo/canals/arrest_helpme.wav"),
		Sound("vo/coast/odessa/female01/nlo_cubdeath01.wav"),
		Sound("vo/coast/odessa/female01/nlo_cubdeath02.wav"),
		Sound("vo/npc/female01/gordead_ans04.wav"),
		Sound("vo/npc/female01/gordead_ans05.wav"),
		Sound("vo/npc/female01/gordead_ans06.wav"),
		Sound("vo/npc/female01/gordead_ans19.wav"),
		Sound("vo/npc/female01/gordead_ques02.wav"),
		Sound("vo/npc/female01/gordead_ques06.wav"),
		Sound("vo/npc/female01/gordead_ques10.wav"),
		Sound("vo/npc/female01/gordead_ques14.wav"),
		Sound("vo/npc/female01/moan01.wav"),
		Sound("vo/npc/female01/moan02.wav"),
		Sound("vo/npc/female01/moan03.wav"),
		Sound("vo/npc/female01/moan04.wav"),
		Sound("vo/npc/female01/moan05.wav"),
		Sound("vo/npc/female01/no01.wav"),
		Sound("vo/npc/female01/no02.wav")
	},
	MaleFreeFall =
	{
		Sound("vo/canals/male01/stn6_incoming.wav"),
		Sound("vo/npc/male01/headsup02.wav"),
		Sound("vo/npc/male01/help01.wav"),
		Sound("vo/npc/male01/incoming02.wav"),
		Sound("vo/npc/male01/pain01.wav"),
		Sound("vo/npc/male01/runforyourlife01.wav"),
		Sound("vo/npc/male01/runforyourlife02.wav"),
		Sound("vo/npc/male01/runforyourlife03.wav"),
		Sound("vo/npc/male01/strider_run.wav"),
		Sound("vo/npc/male01/uhoh.wav"),
		Sound("vo/npc/male01/watchout.wav"),
		Sound("vo/Streetwar/sniper/male01/c17_09_help01.wav"),
		Sound("vo/Streetwar/sniper/male01/c17_09_help02.wav")
	},
	MalePain =
	{
		Sound("vo/npc/male01/imhurt01.wav"),
		Sound("vo/npc/male01/imhurt02.wav"),
		Sound("vo/npc/male01/ow01.wav"),
		Sound("vo/npc/male01/ow02.wav"),
		Sound("vo/npc/male01/pain02.wav"),
		Sound("vo/npc/male01/pain03.wav"),
		Sound("vo/npc/male01/pain04.wav"),
		Sound("vo/npc/male01/pain05.wav"),
		Sound("vo/npc/male01/pain06.wav"),
		Sound("vo/npc/male01/pain07.wav"),
		Sound("vo/npc/male01/pain08.wav"),
		Sound("vo/npc/male01/pain09.wav"),
		Sound("vo/npc/male01/startle01.wav"),
		Sound("vo/npc/male01/startle02.wav")
	},
	MaleDeath =
	{
		Sound("vo/coast/odessa/male01/nlo_cubdeath01.wav"),
		Sound("vo/coast/odessa/male01/nlo_cubdeath02.wav"),
		Sound("vo/npc/male01/gordead_ans04.wav"),
		Sound("vo/npc/male01/gordead_ans05.wav"),
		Sound("vo/npc/male01/gordead_ans06.wav"),
		Sound("vo/npc/male01/gordead_ans19.wav"),
		Sound("vo/npc/male01/gordead_ques02.wav"),
		Sound("vo/npc/male01/gordead_ques06.wav"),
		Sound("vo/npc/male01/gordead_ques10.wav"),
		Sound("vo/npc/male01/gordead_ques14.wav"),
		Sound("vo/npc/male01/moan01.wav"),
		Sound("vo/npc/male01/moan02.wav"),
		Sound("vo/npc/male01/moan03.wav"),
		Sound("vo/npc/male01/moan04.wav"),
		Sound("vo/npc/male01/moan05.wav"),
		Sound("vo/npc/male01/no01.wav"),
		Sound("vo/npc/male01/no02.wav"),
		Sound("vo/trainyard/male01/cit_window_use01.wav")
	},
	ZombieFreeFall =
	{
		Sound("npc/zombie/zombie_voice_idle1.wav"),
		Sound("npc/zombie/zombie_voice_idle2.wav"),
		Sound("npc/zombie/zombie_voice_idle3.wav"),
		Sound("npc/zombie/zombie_voice_idle4.wav"),
		Sound("npc/zombie/zombie_voice_idle5.wav"),
		Sound("npc/zombie/zombie_voice_idle6.wav"),
		Sound("npc/zombie/zombie_voice_idle7.wav"),
		Sound("npc/zombie/zombie_voice_idle8.wav"),
		Sound("npc/zombie/zombie_voice_idle9.wav"),
		Sound("npc/zombie/zombie_voice_idle10.wav"),
		Sound("npc/zombie/zombie_voice_idle11.wav"),
		Sound("npc/zombie/zombie_voice_idle12.wav"),
		Sound("npc/zombie/zombie_voice_idle13.wav"),
		Sound("npc/zombie/zombie_voice_idle14.wav")
	},
	ZombiePain =
	{
		Sound("npc/zombie/zombie_pain1.wav"),
		Sound("npc/zombie/zombie_pain2.wav"),
		Sound("npc/zombie/zombie_pain3.wav"),
		Sound("npc/zombie/zombie_pain4.wav"),
		Sound("npc/zombie/zombie_pain5.wav"),
		Sound("npc/zombie/zombie_pain6.wav")
	},
	ZombieDeath =
	{
		Sound("npc/zombie/zombie_die1.wav"),
		Sound("npc/zombie/zombie_die2.wav"),
		Sound("npc/zombie/zombie_die3.wav"),
		Sound("npc/zombie/zombie_alert1.wav"),
		Sound("npc/zombie/zombie_alert2.wav"),
		Sound("npc/zombie/zombie_alert3.wav")
	}
}

rm.GibModels =
{
	"models/gibs/antlion_gib_medium_1.mdl",
	"models/gibs/antlion_gib_small_1.mdl",
	"models/gibs/antlion_gib_small_2.mdl",
	"models/gibs/antlion_gib_small_3.mdl",
	"models/props_combine/breenbust_Chunk02.mdl",
	"models/props_combine/breenbust_Chunk03.mdl",
	"models/props_combine/breenbust_Chunk04.mdl",
	"models/props_combine/breenbust_Chunk05.mdl",
	"models/props_combine/breenbust_Chunk06.mdl",
	"models/props_combine/breenbust_Chunk07.mdl",
	"models/props_junk/watermelon01_chunk02a.mdl",
	"models/props_junk/watermelon01_chunk02b.mdl",
	"models/props_junk/watermelon01_chunk02c.mdl",
	"models/props_phx/misc/potato.mdl",
	"models/props_wasteland/prison_toiletchunk01f.mdl",
	"models/props_wasteland/prison_toiletchunk01i.mdl",
	"models/props_wasteland/prison_toiletchunk01j.mdl"
}
for _, Gib in pairs(rm.GibModels) do
	util.PrecacheModel(Gib)
end


function rm.GetPlayerModelGender(ModelName)
	for GenderName, GenderIndex in pairs(rm.Genders) do
		for _, Match in pairs(GenderIndex) do
			if string.find(string.lower(ModelName), string.lower(Match)) then
				return GenderName
			end
		end
	end
	return "Male"
end
function rm.ModelIterateBones(Ent, Action)
	for i = 0, Ent:GetBoneCount() - 1 do
		if Action(i, Ent) == false then
			return false
		end
	end
	return true
end
function rm.ModelClosestBone(Ent, Pos, Restrict)
	local TargetIndex, TargetChildIndex, TargetParentIndex = nil, nil, nil
	rm.ModelIterateBones(Ent, function(i)
		if not TargetIndex or (TargetIndex and Ent:GetBonePosition(i):Distance(Pos) < Ent:GetBonePosition(TargetIndex):Distance(Pos)) then
			TargetIndex = i
		end
	end)
	if Target then
		rm.ModelIterateBones(Ent, function(i)
			if Ent:GetBoneParent(i) == TargetIndex then
				TargetChildIndex = i
			end
		end)
		TargetParentIndex = Ragdoll:GetBoneParent(TargetIndex)
	end
	return TargetIndex, TargetChildIndex, TargetParentIndex
end


if SERVER then
	MsgAll("RagMod 2 " ..rm.Version.. " loaded!\n")
	function rm.PlayerRagdolize(Ply, Override)
		local Team = Ply:Team()
		if (Ply.rm_Alive or Override) and Team ~= TEAM_CONNECTING and ((Team ~= TEAM_UNASSIGNED and Team ~= TEAM_SPECTATOR) or not GAMEMODE.TeamBased) and not Ply.rm_Ragdoll and Ply.rm_CanRagdolize then
			local Velocity = Ply:GetVelocity()
			if not Ply.rm_ExitingVehicle and Ply:InVehicle() then
				Velocity = Velocity + Ply:GetVehicle():GetVelocity()
				Ply.rm_ExitingVehicle = true
				Ply:ExitVehicle()
				Ply.rm_ExitingVehicle = false
			end
			if Ply.rm_Alive then
				local Keep = true
				if rm.WeaponDropOnRagdollEnabled:GetBool() then
					Keep = rm.PlayerDropActiveWeapon(Ply, true)
				end
				if rm.RagdollRecoveryWeaponPreserveEnabled:GetBool() then
					Ply.rm_WeaponClass = {}
					Ply.rm_WeaponClip1 = {}
					Ply.rm_WeaponClip2 = {}
					Ply.rm_WeaponAmmo = {}
					Ply.rm_WeaponAmmoType = {}
					local ActiveWeapon = Ply:GetActiveWeapon()
					for _, Item in pairs(Ply:GetWeapons()) do
						if Keep == true or Item ~= ActiveWeapon then
							table.insert(Ply.rm_WeaponClass, Item:GetClass())
							table.insert(Ply.rm_WeaponClip1, Item:Clip1())
							table.insert(Ply.rm_WeaponClip2, Item:Clip2())
							table.insert(Ply.rm_WeaponAmmo, Ply:GetAmmoCount(Item:GetPrimaryAmmoType()))
							table.insert(Ply.rm_WeaponAmmoType, Item:GetPrimaryAmmoType())
							table.insert(Ply.rm_WeaponAmmo, Ply:GetAmmoCount(Item:GetSecondaryAmmoType()))
							table.insert(Ply.rm_WeaponAmmoType, Item:GetSecondaryAmmoType())
						end
					end
					Ply.rm_WeaponSelected = IsValid(ActiveWeapon) and ActiveWeapon:GetClass() or Ply.rm_WeaponSelected or ""
					Ply.rm_WeaponPreserve = true
				end
				Ply:StripWeapons()
			end
			local Ragdoll = ents.Create("prop_ragdoll")
			Ragdoll:SetModel(Ply:GetModel())
			Ragdoll:SetPos(Ply:GetPos())
			Ragdoll:SetAngles(Ply:GetAngles())
			Ragdoll:SetSkin(Ply:GetSkin())
			Ragdoll:SetMaterial(Ply:GetMaterial())
			--Ragdoll:SetBodygroup(Ply:GetBodygroup())
			Ragdoll:SetColor(Ply:GetColor())
			Ragdoll:SetPhysicsAttacker(Ply)
			Ragdoll.rm_Owner = Ply
			Ragdoll.rm_IsRagdoll = true
			Ragdoll:SetNetworkedEntity("rm_Owner", Ply)
			Ragdoll:SetNetworkedBool("rm_IsRagdoll", true)
			Ragdoll.rm_IsUnderwater = Ply.rm_IsUnderwater or false
			Ragdoll:Spawn()
			if Ply:IsOnFire() then
				Ragdoll:Ignite(math.Rand(0, 120))
				Ply:Extinguish()
			end
			rm.RagdollIterateBones(Ragdoll, function(Bone, i)
				local Pos, Angles = Ply:GetBonePosition(Ragdoll:TranslatePhysBoneToBone(i))
				Bone:SetPos(Pos)
				Bone:SetAngles(Angles)
				Bone:SetVelocity(Velocity)
			end)
			rm.RagdollTwitch(Ragdoll, 100)
			Ply:Spectate(OBS_MODE_CHASE)
			Ply:SpectateEntity(Ragdoll)
			Ply:SetVelocity(vector_origin)
			Ply:SetMoveType(MOVETYPE_OBSERVER)
			Ply.rm_Ragdoll = Ragdoll
			Ply:SetNetworkedEntity("rm_Ragdoll", Ragdoll)
			return Ragdoll
		end
	end
	function rm.PlayerRecover(Ply, Reset)
		if rm.RagdollRecoveryEnabled:GetBool() and Ply.rm_Alive and Ply.rm_Ragdoll and Ply.rm_CanRecover and (Ply.rm_RecoveryTimer <= 0 or not rm.RagdollRecoveryDelayEnabled:GetBool()) then
			local Ragdoll = Ply.rm_Ragdoll
			if rm.RagdollRecoverySmoothingEnabled:GetBool() and not Reset and not Ply.rm_Grab and IsValid(Ragdoll) and Ply:WaterLevel() < 2 then
				Ply.rm_CanRecover = false
				local Head = Ragdoll:GetPhysicsObjectNum(10)
				local Multiplier = 0
				local function Move()
					local Tick = FrameTime()
					timer.Simple(Tick, function()
						if IsValid(Ply) and Ply.rm_Alive and IsValid(Ragdoll) then
							local HeightTrace = -(Ragdoll:OBBMaxs().z - Ragdoll:OBBMins().z + 5)
							if rm.RagdollIterateBones(Ragdoll, function(Bone)
								return util.TraceLine(
									{
										start = Bone:GetPos(),
										endpos = Bone:GetPos() + Vector(0, 0, HeightTrace),
										filter = Ragdoll
									}
								).Hit
							end) and Multiplier < 5 and (Multiplier > 0.5 or (Ply:KeyDown(IN_ATTACK) or Ply:KeyDown(IN_ATTACK2) or Ply:KeyDown(IN_JUMP))) then
								local Mass = 0
								rm.RagdollIterateBones(Ragdoll, function(Bone)
									Mass = Mass + Bone:GetMass()
								end)
								local Trace = util.TraceLine(
									{
										start = Head:GetPos(),
										endpos = Head:GetPos() + Vector(0, 0, HeightTrace + 5),
										filter = Ragdoll
									}
								)
								if Trace.Fraction < 0.85 then
									Head:SetVelocity(Vector(0, 0, Mass * 9.84 * (1 - Trace.Fraction) * Multiplier))
									Multiplier = Multiplier + Tick
									Move()
								else
									rm.PlayerRecoverSpawn(Ply, Reset)
								end
							else
								Ply.rm_CanRecover = true
								return
							end
						end
					end)
				end
				Move()
			else
				rm.PlayerRecoverSpawn(Ply, Reset)
			end
		end
	end
	function rm.PlayerRecoverSpawn(Ply, Reset, Force)
		local Ragdoll = Ply.rm_Ragdoll
		local Health = Ply:Health()
		local Armor = Ply:Armor()
		local Angles = Ply:EyeAngles()
		Ply:Spawn()
		if IsValid(Ragdoll) then
			if Reset then
				if not Force and rm.NinjaModeEnabled:GetBool() then
					local Melon = ents.Create("prop_physics")
					Melon:SetModel("models/props_junk/watermelon01.mdl")
					Melon:SetPos(Ragdoll:GetPos())
					Melon:Spawn()
					Melon:GetPhysicsObject():AddAngleVelocity(Vector(0, 0, 50000))
					local Effect = EffectData()
					Effect:SetOrigin(Ragdoll:GetPos())
					util.Effect("Explosion", Effect)
					rm.PlayerHint(Ply, "You disappeared in a cloud of fiery smoke...")
				else
					rm.PlayerHint(Ply, "You have been" ..(Force and " forcefully " or " ").. "reset!")
				end
			else
				if Ragdoll:IsOnFire() then
					Ply:Ignite(math.Rand(0, 120))
				end
				Ply:StripWeapons()
				if rm.RagdollRecoveryWeaponPreserveEnabled:GetBool() then
					if Ply.rm_WeaponPreserve then
						Ply:SetSuppressPickupNotices(true)
						for _, Item in pairs(Ply.rm_WeaponClass) do
							Ply:Give(Item)
						end
						for i, Item in pairs(Ply:GetWeapons()) do
							Item:SetClip1(Ply.rm_WeaponClip1[i])
							Item:SetClip2(Ply.rm_WeaponClip2[i])
						end
						for i, Item in pairs(Ply.rm_WeaponAmmoType) do
							Ply:SetAmmo(Ply.rm_WeaponAmmo[i], Item)
						end
						Ply:SelectWeapon(Ply.rm_WeaponSelected)
						Ply:SetSuppressPickupNotices(false)
						Ply.rm_WeaponClass = nil
						Ply.rm_WeaponClip1 = nil
						Ply.rm_WeaponClip2 = nil
						Ply.rm_WeaponAmmo = nil
						Ply.rm_WeaponAmmoType = nil
						Ply.rm_WeaponSelected = ""
						Ply.rm_WeaponPreserve = false
					end
					timer.Simple(0.1, function() Ply.rm_CanRagdolize = true end)
				end
				Ply:SetSkin(Ragdoll:GetSkin())
				Ply:SetMaterial(Ragdoll:GetMaterial())
				--Ply:SetBodygroup(Ragdoll:GetBodygroup())
				Ply:SetColor(Ragdoll:GetColor())
				Ply:SetHealth(Health)
				Ply:SetArmor(Armor)
				Ply:SetPos(
					util.TraceLine(
						{
							start = Ragdoll:GetPos() + Vector(0, 0, 10),
							endpos = Ragdoll:GetPos() - Vector(0, 0, 10),
							filter = {Ply, Ragdoll}
						}
					).HitPos
				)
				Ply:SetEyeAngles(Angles)
				Ply:SetVelocity(Ragdoll:GetVelocity())
				if Force then
					rm.PlayerHint(Ply, "You have been forcefully recovered!")
				end
			end
		else
			if Force then
				rm.PlayerHint(Ply, "You have been forcefully reset!")
			else
				rm.PlayerHint(Ply, "You have lost your body and have been reset!")
			end
		end
		rm.PlayerRemoveRagdoll(Ply)
		Ply.rm_CanRecover = true
	end
	function rm.PlayerSpawn(Ply)
		if (not Ply.rm_Alive or not Ply.rm_Ready) then
			if not Ply.rm_Ready then
				rm.PlayerHint(Ply, "This server is running RagMod 2 " ..rm.Version.. ".", 20)
				if GAMEMODE.IsSandboxDerived then
					rm.PlayerHint(Ply, "See \"Spawn Menu > Options > RagMod 2\" for more information.", 20, 2.5)
				else
					rm.PlayerHint(Ply, "Use the console command rm_help for more information.", 20, 2.5)
				end
				Ply.rm_Ragdolls = {}
				rm.PlayerRemoveRagdollVariables(Ply)
			elseif not Ply.rm_Alive then
				Ply:SetMaterial(nil)
				Ply:SetColor(Color(255, 255, 255, 255))
				if not rm.RagdollKeepEnabled:GetBool() then
					rm.PlayerRemoveRagdoll(Ply)
				else
					rm.PlayerRemoveRagdollVariables(Ply)
				end
			end
			Ply.rm_CanRagdolize = true
			Ply.rm_CanRecover = true
			Ply.rm_SoundTimer = 0
			Ply.rm_Oxygen = 0
			Ply:SetNetworkedFloat("rm_Oxygen", 1)
			Ply.rm_Attacker = nil
			Ply.rm_Inflictor = nil
			Ply:SetNetworkedEntity("rm_Killer", NULL)
			Ply:SetNetworkedFloat("rm_DeathTime", 0)
			Ply:SetNetworkedFloat("rm_SpawnTime", 0)
			Ply.rm_WeaponClass = nil
			Ply.rm_WeaponClip1 = nil
			Ply.rm_WeaponClip2 = nil
			Ply.rm_WeaponAmmo = nil
			Ply.rm_WeaponSelected = ""
			Ply.rm_WeaponPreserve = false
			Ply.rm_WeaponLowered = false
			Ply.rm_RecoveryTimer = 0
			Ply.rm_Move = false
			Ply.rm_MoveTimer = 0
			Ply.rm_MoveSwitch = false
			Ply.rm_Twitch = false
			Ply.rm_Grab = false
			Ply.rm_Parachute = false
			Ply.rm_ParachuteEntity = nil
			Ply.rm_Kills = 0
			Ply:SetNetworkedInt("rm_Kills", 0)
			Ply.rm_Alive = true
			Ply.rm_Ready = true
		end
	end
	function rm.NPCRagdolize(NPC)
		for _, ClassName in pairs(string.Explode(",", rm.NPCRagdolizeBlacklist:GetString())) do
			if NPC:GetClass() == ClassName or NPC:GetClass() == "npc_" ..ClassName or NPC:GetClass() == "monster_" ..ClassName or NPC:GetClass() == "snpc_" ..ClassName then
				return
			end
		end
		local Ragdoll = ents.Create("prop_ragdoll")
		Ragdoll:SetModel(NPC:GetModel())
		Ragdoll:SetPos(NPC:GetPos())
		Ragdoll:SetAngles(NPC:GetAngles())
		Ragdoll:SetSkin(NPC:GetSkin())
		Ragdoll:SetMaterial(NPC:GetMaterial())
		--Ragdoll:SetBodygroup(NPC:GetBodygroup())
		Ragdoll:SetColor(NPC:GetColor())
		Ragdoll:SetPhysicsAttacker(NPC)
		Ragdoll.rm_Owner = NPC
		Ragdoll.rm_IsRagdoll = true
		Ragdoll:SetNetworkedBool("rm_IsRagdoll", true)
		Ragdoll.rm_IsNPCRagdoll = true
		Ragdoll.rm_IsUnderwater = false
		Ragdoll:Spawn()
		if NPC:IsOnFire() then
			Ragdoll:Ignite(math.Rand(0, 120))
			NPC:Extinguish()
		end
		rm.RagdollIterateBones(Ragdoll, function(Bone, i)
			local Pos, Angles = NPC:GetBonePosition(Ragdoll:TranslatePhysBoneToBone(i))
			Bone:SetPos(Pos)
			Bone:SetAngles(Angles)
		end)
		if NPC.rm_DamageInfo then
			if NPC.rm_DamageInfo:GetDamageType() == DMG_FALL then
				local Velocity = NPC.rm_DamageInfo:GetDamageForce() * 10
				if Velocity == vector_origin then
					Velocity = vector_up * -150
				end
				rm.RagdollIterateBones(Ragdoll, function(Bone)
					Bone:SetVelocity(Velocity)
				end)
			else
				Ragdoll:TakeDamageInfo(NPC.rm_DamageInfo)
			end
		end
		rm.RagdollTwitch(Ragdoll, 100)
		NPC.rm_Ragdoll = Ragdoll
		NPC:SetNetworkedEntity("rm_Ragdoll", Ragdoll)
		local RagdollCount = 0
		local FirstRagdoll = nil
		if rm.RagdollKeepEnabled:GetBool() and rm.RagdollKeepNPCValue:GetInt() > 0 then
			for _, Ent in pairs(ents.FindByClass("prop_ragdoll")) do
				if Ent.rm_IsNPCRagdoll then
					FirstRagdoll = IsValid(FirstRagdoll) and FirstRagdoll or Ent
					RagdollCount = RagdollCount + 1
					if RagdollCount > rm.RagdollKeepNPCValue:GetInt() then
						rm.RagdollRemove(FirstRagdoll)
					end
				end
			end
		elseif not rm.RagdollKeepEnabled:GetBool() then
			timer.Simple(10, function() rm.RagdollRemove(Ragdoll) end)
		end
		return Ragdoll
	end
	function rm.PlayerHint(Ply, Text, Time, Delay)
		if rm.HintEnabled:GetBool() then
			local function ShowHint()
				if GAMEMODE.IsSandboxDerived then
					Ply:SendLua("GAMEMODE:AddNotify([[[RagMod] " ..Text.. "]], NOTIFY_GENERIC, " ..(Time or "rm.HintTime:GetFloat()").. ") surface.PlaySound(\"ambient/water/drip" ..math.random(1, 4).. ".wav\")")
				else
					Ply:ChatPrint("[RagMod] " ..Text)
				end
			end
			if Delay then
				timer.Simple(Delay, ShowHint)
			else
				ShowHint()
			end
		end
	end
	function rm.PlaySound(Ent, Mode)
		if rm.SoundEnabled:GetBool() then
			local Gender = nil
			local SoundTable = rm.Sounds[Mode]
			if not SoundTable then
				Gender = rm.GetPlayerModelGender(Ent:GetModel())
				SoundTable = rm.Sounds[Gender .. Mode]
			end
			if SoundTable and #SoundTable > 0 then
				if Gender then
					for Name, Index in pairs(rm.Sounds) do
						if Gender == string.sub(Name, 1, string.len(Gender)) then
							for _, Value in pairs(Index) do
								Ent:StopSound(Value)
							end
						end
					end
				end
				Ent:EmitSound(table.Random(SoundTable), rm.SoundVolume:GetFloat(), math.Rand(95, 105) * ((GetConVar("host_timescale"):GetFloat() + 1) / 2))
			end
		end
	end
	function rm.PlayerPlaySound(Ply, Mode)
		if rm.SoundEnabled:GetBool() and Ply.rm_SoundTimer >= rm.SoundDelay:GetFloat() then
			rm.PlaySound(IsValid(Ply.rm_Ragdoll) and Ply.rm_Ragdoll or Ply, Mode)
			Ply.rm_SoundTimer = 0
		end
	end
	function rm.RagdollIterateBones(Ragdoll, Action)
		for i = 0, Ragdoll:GetPhysicsObjectCount() - 1 do
			local Bone = Ragdoll:GetPhysicsObjectNum(i)
			if IsValid(Bone) then
				if Action(Bone, i, Ragdoll) == false then
					return false
				end
			end
		end
		return true
	end
	function rm.RagdollClosestBone(Ragdoll, Pos, Restrict)
		local Target, TargetIndex, TargetChild, TargetChildIndex, TargetParent, TargetParentIndex = nil, nil, nil, nil, nil, nil
		rm.RagdollIterateBones(Ragdoll, function(Bone, i)
			local ModelBone = Ragdoll:TranslatePhysBoneToBone(i)
			if i ~= 0 and (not Restrict or (Restrict and (not Ragdoll["rm_DecapitatedBone" ..i] and ModelBone ~= Ragdoll:LookupBone("ValveBiped.Bip01_Spine1") and ModelBone ~= Ragdoll:LookupBone("ValveBiped.Bip01_Spine2")))) and (not Target or (Target and Bone:GetPos():Distance(Pos) < Target:GetPos():Distance(Pos))) then
				Target = Bone
				TargetIndex = i
			end
		end)
		if Target then
			rm.RagdollIterateBones(Ragdoll, function(Bone, i)
				if Ragdoll:TranslateBoneToPhysBone(Ragdoll:GetBoneParent(Ragdoll:TranslatePhysBoneToBone(i))) == TargetIndex then
					TargetChild = Bone
					TargetChildIndex = i
				end
			end)
			TargetParentIndex = Ragdoll:TranslateBoneToPhysBone(Ragdoll:GetBoneParent(Ragdoll:TranslatePhysBoneToBone(TargetIndex)))
			if TargetParentIndex and TargetParentIndex ~= TargetIndex then
				rm.RagdollIterateBones(Ragdoll, function(Bone, i)
					if i == TargetParentIndex then
						TargetParent = Bone
					end
				end)
			end
		end
		return Target, TargetIndex, TargetChild, TargetChildIndex, TargetParent, TargetParentIndex
	end
	function rm.RagdollHideChildBones(Ragdoll, MasterBone)
		Ragdoll:ManipulateBoneScale(MasterBone, vector_origin)
		Ragdoll:ManipulateBonePosition(MasterBone, vector_origin)
		for _, Bone in pairs(Ragdoll:GetChildBones(MasterBone)) do
			Ragdoll:ManipulateBoneScale(Bone, vector_origin)
			Ragdoll:ManipulateBonePosition(Bone, Ragdoll:GetPhysicsObjectNum(Ragdoll:TranslateBoneToPhysBone(Bone)):WorldToLocal(Ragdoll:GetBonePosition(MasterBone)))
		end
	end
	function rm.RagdollTwitch(Ragdoll, Amount)
		rm.RagdollIterateBones(Ragdoll, function(Bone, i)
			if i ~= 0 then
				Bone:AddVelocity(VectorRand() * Amount)
			end
		end)
	end
	function rm.RagdollDeath(Ragdoll)
		if rm.RagdollDeathEffectEnabled:GetBool() then
			local Bone = Ragdoll:GetPhysicsObjectNum(Ragdoll:TranslateBoneToPhysBone(math.random(0, 1) == 1 and 0 or (Ragdoll:LookupBone("ValveBiped.Bip01_Head1") or Ragdoll:LookupBone("head") or 0)))
			Velocity = math.max(Bone:GetVelocity():Length() / 80, 1)
			local Multiplier = 10000 * (1 / Velocity) * rm.RagdollDeathEffectMultiplier:GetFloat()
			local Count = math.Rand(1, 5)
			local CountMax = Count
			local function Move()
				local Tick = FrameTime()
				timer.Simple(Tick, function()
					if IsValid(Ragdoll) then
						Bone:SetDamping(0, 0)
						if Count > 0 then
							local Height = Ragdoll:OBBMaxs().z - Ragdoll:OBBMins().z
							if rm.RagdollIterateBones(Ragdoll, function(Bone)
								Trace = util.TraceLine(
									{
										start = Bone:GetPos(),
										endpos = Bone:GetPos() + Vector(0, 0, -Height),
										filter = Ragdoll
									}
								)
								if not Trace.Hit then
									return false
								end
							end) then
								Bone:SetDamping(Multiplier * (Count / CountMax), 0)
								Count = Count - Tick
								Move()
							end
						end
					end
				end)
			end
			Move()
		end
		if rm.RagdollDeathFacePoseEnabled:GetBool() then
			local Count = math.Rand(2, 3)
			local CountMax = Count
			local function Pose()
				local Tick = FrameTime()
				timer.Simple(Tick, function()
					if IsValid(Ragdoll) and Count > 0 then
						local Value = 1 - math.cos((Count / CountMax) * (math.pi / 2))
						local FlexNum = Ragdoll:GetFlexNum() - 1
						if FlexNum <= 0 then
							return
						end
						for i = 0, FlexNum - 1 do
							local Name = Ragdoll:GetFlexName(i)
							if Name == "jaw_drop" or Name == "right_part" or Name == "left_part" or Name == "right_mouth_drop" or Name == "left_mouth_drop" then
								Ragdoll:SetFlexWeight(i, Value)
							end
						end
						Count = Count - Tick
						Pose()
					end
				end)
			end
			Pose()
		end
		if rm.RagdollTwitchEnabled:GetBool() and rm.RagdollTwitchOnDeathEnabled:GetBool() then
			local Count = math.Rand(12, 15)
			local CountMax = Count
			local function Move()
				local Tick = FrameTime()
				timer.Simple(Tick, function()
					if IsValid(Ragdoll) then
						Count = Count - Tick
						if Count <= 0 then
							return
						end
						local Multiplier = Count / CountMax
						if Ragdoll:IsOnFire() then
							rm.RagdollTwitch(Ragdoll, 50 * Multiplier)
						else
							rm.RagdollIterateBones(Ragdoll, function(Bone, i)
								if i ~= 0 and math.random(0, 1000 * (1 - Multiplier)) == 0 then
									Bone:AddVelocity(VectorRand() * 80 * Multiplier)
								end
							end)
						end
						Move()
					end
				end)
			end
			Move()
		end
	end
	function rm.PlayerDropActiveWeapon(Ply, Advanced)
		local Weapon = Ply:GetActiveWeapon()
		if IsValid(Weapon) and Weapon:GetClass() ~= "swep_parachute" and Weapon:GetClass() ~= "swep_climbrope" and Weapon:GetModel() ~= "" then
			local Keep = false
			local Class = Weapon:GetClass()
			if Advanced == true then
				if Weapon:GetPrimaryAmmoType() ~= -1 then
					local Count = 0
					if Class == "weapon_ar2" then
						Count = 30
					elseif Class == "weapon_crossbow" then
						if Weapon:Clip1() == 0 then
							Count = 5
						else
							Count = 4
						end
					elseif Class == "weapon_deagle" then
						Count = 40
					elseif Class == "weapon_frag" then
						Keep = true
						Count = 1
					elseif Class == "weapon_glock" then
						Count = 8
					elseif Class == "weapon_m4" then
						Count = 25
					elseif Class == "weapon_mac10" then
						Count = 50
					elseif Class == "weapon_para" then
						Count = 100
					elseif Class == "weapon_pumpshotgun" then
						Count = 8
					elseif Class == "weapon_rpg" then
						Count = 3
					elseif Class == "weapon_tmp" then
						Count = 25
					elseif Class == "weapon_slam" then
						Keep = true
						Count = 3
					elseif Weapon:Clip1() == -1 and Weapon:Clip2() == -1 then
						Count = 1
					end
					if Count > 0 then
						if Ply:GetAmmoCount(Weapon:GetPrimaryAmmoType()) >= Count then
							Ply:RemoveAmmo(Count, Weapon:GetPrimaryAmmoType())
							if Ply:GetAmmoCount(Weapon:GetPrimaryAmmoType()) == 0 then
								Keep = false
							end
						else
							return
						end
					end
				end
			end
			local NewWeapon = ents.Create(Weapon:GetClass())
			NewWeapon:SetKeyValue("spawnflags", "2")
			NewWeapon:Spawn()
			local Trace = util.TraceLine(
				{
					start = Ply:EyePos(),
					endpos = Ply:EyePos() + (Ply:GetAimVector() * 100),
					filter = Ply
				}
			)
			if Trace.Hit and Advanced then
				NewWeapon:SetPos(Trace.HitPos + Vector(0, 0, 10))
				NewWeapon:SetAngles(Ply:GetAngles() + Angle(0, 90 * (math.random(0, 1) == 1 and -1 or 1), math.random(0, 1) == 1 and (math.random(0, 1) == 1 and 90 or -90) or 0))
			else
				NewWeapon:SetPos(Ply:EyePos() + (Ply:GetAimVector() * 30))
				NewWeapon:SetAngles(Ply:EyeAngles())
				if IsValid(NewWeapon:GetPhysicsObject()) then
					if not Advanced then
						NewWeapon:GetPhysicsObject():AddAngleVelocity(Vector(math.Rand(-600, 600), math.Rand(-600, 600), math.Rand(-600, 600)))
					end
					NewWeapon:GetPhysicsObject():SetVelocity(Ply:GetVelocity() + (Ply:GetAimVector() * (Advanced and 500 or math.Rand(50, 150))))
				end
			end
			NewWeapon:SetClip1(Weapon:Clip1())
			NewWeapon:SetClip2(Weapon:Clip2())
			timer.Simple(2, function()
				if IsValid(NewWeapon) then
					NewWeapon:SetKeyValue("spawnflags", "0")
				end
			end)
			if not Keep then
				Weapon:Remove()
			end
			return Keep
		end
		return true
	end
	function rm.PlayerRemoveRagdollVariables(Ply)
		Ply.rm_Ragdoll = nil
		Ply:SetNetworkedEntity("rm_Ragdoll", NULL)
	end
	function rm.PlayerRemoveRagdoll(Ply)
		if IsValid(Ply.rm_Ragdoll) then
			Ply.rm_Ragdoll:Remove()
		end
		rm.PlayerRemoveRagdollVariables(Ply)
	end
	function rm.RagdollRemove(Ragdoll, Mode)
		Mode = Mode or 2
		if Mode == 1 then
			Ragdoll:Remove()
		elseif Mode == 2 or Mode == 3 then
			Ragdoll.rm_IsRagdoll = false
			Ragdoll:SetNetworkedBool("rm_IsRagdoll", false)
			Ragdoll.rm_IsNPCRagdoll = false
			Ragdoll:SetNetworkedBool("rm_IsNPCRagdoll", false)
			Ragdoll.rm_IsLimb = false
			Ragdoll:SetNetworkedBool("rm_IsLimb", false)
			if Mode == 2 then
				Ragdoll:SetMoveType(0)
				Ragdoll:SetSolid(0)
				Ragdoll:DrawShadow(false)
				Ragdoll:SetRenderMode(RENDERMODE_TRANSALPHA)
				local Alpha = 1
				local function Fade()
					local Tick = FrameTime()
					timer.Simple(Tick, function()
						Alpha = Alpha - Tick
						if IsValid(Ragdoll) then
							if Alpha <= 0 then
								Ragdoll:Remove()
							else
								local RagdollColor = Ragdoll:GetColor()
								Ragdoll:SetColor(Color(RagdollColor.r, RagdollColor.g, RagdollColor.b, Alpha * 255))
								Fade()
							end
						end
					end)
				end
				Fade()
			end
		end
	end
	function rm.PlayerGrab(Ply)
		if rm.RagdollGrabEnabled:GetBool() then
			if Ply.rm_Grab and IsValid(Ply.rm_Ragdoll) then
				if IsValid(Ply.rm_GrabLeftConstraint) then
					Ply.rm_GrabLeftConstraint:Remove()
				end
				if IsValid(Ply.rm_GrabRightConstraint) then
					Ply.rm_GrabRightConstraint:Remove()
				end
				Ply.rm_Grab = false
			elseif not Ply.rm_Grab then
				if not Ply.rm_Ragdoll then
					local Ent = Ply:GetGroundEntity()
					if IsValid(Ent) or Ent:EntIndex() == 0 then
						local Ragdoll = rm.PlayerRagdolize(Ply)
						if IsValid(Ragdoll) then
							Ply.rm_RecoveryTimer = rm.RagdollRecoveryDelayDefault:GetFloat()
							local Strength = rm.RagdollGrabStrength:GetFloat()
							local LeftHand = Ragdoll:GetPhysicsObjectNum(5)
							local RightHand = Ragdoll:GetPhysicsObjectNum(7)
							local LeftFoot = Ragdoll:GetPhysicsObjectNum(12)
							local RightFoot = Ragdoll:GetPhysicsObjectNum(9)
							local Head = Ragdoll:GetPhysicsObjectNum(10)
							local LeftConstraint = constraint.Weld(Ragdoll, Ent, 9, 0, Strength, false)
							Ply.rm_GrabLeftConstraint = LeftConstraint
							local RightConstraint = constraint.Weld(Ragdoll, Ent, 12, 0, Strength, false)
							Ply.rm_GrabRightConstraint = RightConstraint
							Ply.rm_Grab = true
							local function Balance()
								timer.Simple(FrameTime(), function()
									if IsValid(Ply) and Ply.rm_Alive and IsValid(Ragdoll) and (IsValid(LeftConstraint) or IsValid(RightConstraint)) then
										LeftHand:AddVelocity((Vector(0, 0, 30) + (Ply:GetAngles():Right() * -20)) * math.Rand(0.5, 1))
										RightHand:AddVelocity((Vector(0, 0, 30) + (Ply:GetAngles():Right() * 20)) * math.Rand(0.5, 1))
										Head:AddVelocity(Vector(0, 0, 140))
										if IsValid(LeftConstraint) then
											if not IsValid(RightConstraint) then
												Ply.rm_Twitch = true
												if math.random(1, 1000) == 1 then
													LeftConstraint:Remove()
												end
											end
											local Pos = LeftFoot:GetPos()
											local Trace = util.TraceLine({start = Pos, endpos = Pos - Vector(0, 0, 25), filter = {Ragdoll, Ply}, mask = MASK_SOLID})
											if Trace.Entity ~= Ent then
												LeftConstraint:Remove()
											end
										end
										if IsValid(RightConstraint) then
											if not IsValid(LeftConstraint) then
												Ply.rm_Twitch = true
												if math.random(1, 1000) == 1 then
													RightConstraint:Remove()
												end
											end
											local Pos = RightFoot:GetPos()
											local Trace = util.TraceLine({start = Pos, endpos = Pos - Vector(0, 0, 25), filter = {Ragdoll, Ply}, mask = MASK_SOLID})
											if Trace.Entity ~= Ent then
												RightConstraint:Remove()
											end
										end
										if Ply.rm_Twitch and math.random(1, 100) == 1 then
											rm.PlayerPlaySound(Ply, "FreeFall")
										end
										Balance()
									else
										if IsValid(LeftConstraint) then
											LeftConstraint:Remove()
										end
										if IsValid(RightConstraint) then
											RightConstraint:Remove()
										end
										Ply.rm_Twitch = false
										Ply.rm_Grab = false
									end
								end)
							end
							Balance()
						end
					end
				end
			end
		end
	end
	function rm.PlayerParachute(Ply)
		if rm.RagdollParachuteEnabled:GetBool() and Ply.rm_Alive and not Ply.rm_Parachute then
			local Ragdoll = Ply.rm_Ragdoll
			if not Ragdoll then
				Ply.rm_RecoveryTimer = rm.RagdollRecoveryDelayDefault:GetFloat()
				Ragdoll = rm.PlayerRagdolize(Ply)
			end
			if IsValid(Ragdoll) then
				local Parachute = ents.Create("prop_physics")
				Parachute:SetModel("models/props_debris/metal_panel01a.mdl")
				Parachute:SetPos(Ragdoll:GetPos() + Vector(0, 0, 40))
				Parachute:SetAngles(Angle(90, -90, Ply:EyeAngles().yaw))
				Parachute:SetMaterial("models/props_c17/FurnitureFabric003a")
				Parachute:Spawn()
				Parachute:GetPhysicsObject():SetMass(40)
				Parachute:GetPhysicsObject():SetDamping(15 * rm.RagdollParachuteMultiplier:GetFloat(), math.Rand(1, 2))
				local LeftFrontConstraint, LeftFrontRope = constraint.Elastic(Ragdoll, Parachute, 1, 0, Vector(6, 5, 5), Vector(3, 22, -60), 200, 100, 0, "cable/cable", 1, true)
				local LeftBackConstraint, LeftFrontRope = constraint.Elastic(Ragdoll, Parachute, 1, 0, Vector(6, -3, 5), Vector(3, -22, -60), 200, 100, 0, "cable/cable", 1, true)
				local RightFrontConstraint, RightFrontRope = constraint.Elastic(Ragdoll, Parachute, 1, 0, Vector(6, 5, -5), Vector(3, 22, 60), 200, 100, 0, "cable/cable", 1, true)
				local RightBackConstraint, RightBackRope = constraint.Elastic(Ragdoll, Parachute, 1, 0, Vector(6, -3, -5), Vector(3, -22, 60), 200, 100, 0, "cable/cable", 1, true)
				local LeftHandConstraint, LeftHandRope = constraint.Elastic(Ragdoll, Parachute, 5, 0, Vector(5, -2, 0), Vector(3, 0, -50), 150, 100, 0, "cable/cable", 0.5, true)
				local RightHandConstraint, RightHandRope = constraint.Elastic(Ragdoll, Parachute, 7, 0, Vector(5, -2, 0), Vector(3, 0, 50), 150, 100, 0, "cable/cable", 0.5, true)
				Ply.rm_ParachuteEntity = Parachute
				Ply.rm_Parachute = true
				local function Check()
					timer.Simple(FrameTime(), function()
						if IsValid(Ragdoll) and IsValid(Parachute) and (not IsValid(Ply) or (Ply and (not Ply.rm_Ragdoll or (Ply.rm_Ragdoll == Ragdoll and Ply.rm_Parachute)))) then
							Check()
						else
							if IsValid(LeftFrontConstraint) then
								LeftFrontConstraint:Remove()
							end
							if IsValid(LeftBackConstraint) then
								LeftBackConstraint:Remove()
							end
							if IsValid(RightFrontConstraint) then
								RightFrontConstraint:Remove()
							end
							if IsValid(RightBackConstraint) then
								RightBackConstraint:Remove()
							end
							if IsValid(LeftHandConstraint) then
								LeftHandConstraint:Remove()
							end
							if IsValid(RightHandConstraint) then
								RightHandConstraint:Remove()
							end
							if IsValid(Parachute) then
								Parachute:Remove()
							end
							Ply.rm_ParachuteEntity = nil
							Ply.rm_Parachute = false
						end
					end)
				end
				Check()
			end
		end
	end
	hook.Add("Tick", "rm_sv_Tick", function()
		local Enabled = rm.Enabled:GetBool()
		if rm.EnabledDelta ~= Enabled then
			rm.EnabledDelta = Enabled
			for _, Ply in pairs(player.GetAll()) do
				rm.PlayerHint(Ply, "RagMod 2 is now " ..(rm.EnabledDelta and "en" or "dis").. "abled.", 5)
				if IsValid(Ply.rm_Ragdoll) then
					Ply:Spawn()
				end
			end
		end
		if Enabled then
			local rm_Tick = FrameTime()
			if rm.NPCRagdolizeOnDeathEnabled:GetBool() then
				if not GetConVar("ai_serverragdolls"):GetBool() then
					RunConsoleCommand("ai_serverragdolls", "1")
					for _, Ply in pairs(player.GetAll()) do
						rm.PlayerHint(Ply, "ai_serverragdolls needs to be enabled for NPC death ragdolization compatibility.", 10, 1)
					end
				end
			end
			for _, Item in pairs(ents.GetAll()) do
				if Item.rm_IsRagdoll then
					if rm.RagdollTwitchEnabled:GetBool() and rm.RagdollTwitchOnSpeedEnabled:GetBool() then
						rm.RagdollTwitch(Item, Item:GetVelocity():Length() * 0.015 * rm.RagdollTwitchOnSpeedMultiplier:GetFloat())
					end
					if Item:WaterLevel() == 3 then
						if Item:IsOnFire() and math.random(1, 15) == 1 then
							Item:Extinguish()
						end
						if Item.rm_IsUnderwater ~= true then
							Item.rm_IsUnderwater = true
							if Item:GetVelocity():Length() > math.Rand(150, 250) then
								local Water = EffectData()
								Water:SetOrigin(Item:GetPos())
								Water:SetScale(Item:GetVelocity():Length() / 10)
								util.Effect("WaterSplash", Water)
							end
						end
					else
						Item.rm_IsUnderwater = false
					end
				end
			end
			for _, Ply in pairs(player.GetAll()) do
				if Ply:WaterLevel() == 3 then
					Ply.rm_IsUnderwater = true
					Ply:Extinguish()
					if rm.OxygenEnabled:GetBool() then
						Ply.rm_Oxygen = math.min(Ply.rm_Oxygen + rm_Tick, rm.OxygenValue:GetFloat())
					end
				else
					Ply.rm_IsUnderwater = false
					if rm.OxygenEnabled:GetBool() then
						Ply.rm_Oxygen = math.max(Ply.rm_Oxygen - rm_Tick * rm.OxygenRegenerateValue:GetFloat(), 0)
					end
				end
				if Ply.rm_Alive then
					if rm.OxygenEnabled:GetBool() and Ply.rm_Oxygen >= rm.OxygenValue:GetFloat() then
						if math.random(1, rm.OxygenDrownValue:GetFloat()) == 1 then
							Ply:SetHealth(math.max(Ply:Health() - math.random(), 0))
							rm.PlayerPlaySound(Ply, "PlayerDrown")
							if not Ply.rm_Ragdoll then
								Ply:ViewPunch(Angle(math.Rand(-4, 4), math.Rand(-4, 4), 0))
							end
							if Ply:Health() <= 0 then
								if rm.WeaponDropOnDrownEnabled:GetBool() then
									rm.PlayerDropActiveWeapon(Ply, false)
								end
								Ply:Kill()
							end
						end
					end
				else
					Ply.rm_Move = false
					Ply.rm_Twitch = false
					Ply.rm_Grab = false
				end
				local Ragdoll = Ply.rm_Ragdoll
				if IsValid(Ragdoll) then
					if Ply:FlashlightIsOn() then
						Ply:Flashlight(false)
					end
					Ply:SetPos(Ragdoll:GetPos() + Vector(0, 0, 9.5))
					if Ply.rm_Alive then
						if not Ply.rm_Move and math.random(1, 150) == 1 and Ragdoll:GetVelocity():Length() >= rm.RagdolizeOnSpeedValue:GetFloat() / 3 then
							rm.PlayerPlaySound(Ply, "FreeFall")
						end
						if rm.RagdollTwitchEnabled:GetBool() and ((Ply.rm_Twitch and rm.RagdollTwitchOnCommandEnabled:GetBool()) or Ply.rm_Oxygen >= rm.OxygenValue:GetFloat()) then
							rm.RagdollIterateBones(Ragdoll, function(Bone, i)
								if math.random(1, 5) == 1 and (i == 10 or i == 5 or i == 7 or i == 13 or i == 14) then
									Bone:AddVelocity(VectorRand() * 325)
								end
							end)
							if math.random(1, 400) == 1 then
								Ragdoll:Extinguish()
							end
							if Ragdoll.rm_IsUnderwater and math.random(1, 50) == 1 then
								local Water = EffectData()
								Water:SetOrigin(Ragdoll:GetPos() + VectorRand() * 20)
								Water:SetScale(math.Rand(2, 6))
								util.Effect("WaterSplash", Water)
							end
						end
						if rm.RagdollMoveEnabled:GetBool() and Ply.rm_Move then
							local Velocity = Ragdoll:GetVelocity()
							if Ply.rm_Parachute then
								local Force = Ply:GetAimVector() * math.Clamp(Ragdoll:GetVelocity():Length() / 8, 15, 1000)
								local ForceRight = Ply:EyeAngles():Right() * 100

								Ply.rm_ParachuteEntity:GetPhysicsObject():SetVelocity(Velocity + Force)

								local Bone = Ragdoll:GetPhysicsObjectNum(1)
								Bone:SetVelocity(Velocity + Force / 7)

								Bone = Ragdoll:GetPhysicsObjectNum(10)
								Bone:SetVelocity(Velocity + Force / 15)

								Bone = Ragdoll:GetPhysicsObjectNum(5)
								Bone:SetVelocity(Velocity - ForceRight)

								Bone = Ragdoll:GetPhysicsObjectNum(7)
								Bone:SetVelocity(Velocity + ForceRight)
							else
								local Superman = rm.RagdollMoveSupermanModeEnabled:GetBool()
								if Velocity:Length() < 200 then
									if Ply.rm_MoveTimer >= 0.5 then
										Ply.rm_MoveTimer = 0
										Ply.rm_MoveSwitch = not Ply.rm_MoveSwitch
									end
									local Force = (Ragdoll.rm_IsUnderwater and Ply:GetAimVector() or Ply:EyeAngles():Forward()) * (Ply.rm_MoveTimer / 0.5) * 900

									local Bone = Ragdoll:GetPhysicsObjectNum(1)
									if not Ply.rm_Grab then
										Bone:ApplyForceOffset(-Bone:GetAngles():Right(), Vector(0, 0, 10000))
									end
									Bone:SetVelocity(Velocity + Force / 35)

									Bone = Ragdoll:GetPhysicsObjectNum(10)
									Bone:SetVelocity(Velocity + Force / 10)

									Bone = Ragdoll:GetPhysicsObjectNum(Ply.rm_MoveSwitch and 5 or 7)
									Bone:SetVelocity(Velocity + Force)
									Bone = Ragdoll:GetPhysicsObjectNum(Ply.rm_MoveSwitch and 4 or 6)
									Bone:SetVelocity(Velocity + Force / 1.5)

									Bone = Ragdoll:GetPhysicsObjectNum(Ply.rm_MoveSwitch and 7 or 5)
									Bone:SetVelocity(Velocity + Force / 3)
									Bone = Ragdoll:GetPhysicsObjectNum(Ply.rm_MoveSwitch and 6 or 4)
									Bone:SetVelocity(Velocity - Force / 2)
								elseif Superman or Velocity.z < -300 then
									local Multiplier = Superman and 1 or (1 - (1 / ((-(Velocity.z + 300) / 1000) + 1)))
									if Ply:GetAimVector().z <= -0.99 then
										local ForceForward = Ply:EyeAngles():Forward() * 100 * Multiplier
										local ForceUp = Vector(0, 0, Multiplier * 200)
										local ForceDown = -ForceUp * 2

										local Bone = Ragdoll:GetPhysicsObjectNum(1)
										Bone:SetVelocity(Velocity + ForceDown * 0.3)

										Bone = Ragdoll:GetPhysicsObjectNum(10)
										Bone:SetVelocity(Velocity + ForceForward + ForceDown)

										Bone = Ragdoll:GetPhysicsObjectNum(5)
										Bone:SetVelocity(Velocity + ForceUp - (ForceForward / 2))

										Bone = Ragdoll:GetPhysicsObjectNum(7)
										Bone:SetVelocity(Velocity + ForceUp - (ForceForward / 2))

										Bone = Ragdoll:GetPhysicsObjectNum(12)
										Bone:SetVelocity(Velocity + ForceUp - (ForceForward / 2))

										Bone = Ragdoll:GetPhysicsObjectNum(9)
										Bone:SetVelocity(Velocity + ForceUp - (ForceForward / 2))
									else
										local ForceForward = (Superman and (Ply:GetAimVector() * 250) or (Ply:EyeAngles():Forward() * 150)) * Multiplier
										local ForceRight = Ply:EyeAngles():Right() * 100 * Multiplier
										local ForceUp = Vector(0, 0, 70) * Multiplier

										local Bone = Ragdoll:GetPhysicsObjectNum(1)
										Bone:ApplyForceOffset(-Bone:GetAngles():Right(), Vector(0, 0, 10000 * Multiplier))
										Bone:SetVelocity(Velocity + (ForceUp / 10) + (ForceForward / 25))

										Bone = Ragdoll:GetPhysicsObjectNum(5)
										Bone:SetVelocity(Velocity + (ForceUp / 2) + ForceForward - (Superman and vector_origin or ForceRight))
										Bone = Ragdoll:GetPhysicsObjectNum(4)
										Bone:SetVelocity(Velocity + (ForceUp / 2) + (ForceForward / 2) - (Superman and vector_origin or ForceRight))
										Bone = Ragdoll:GetPhysicsObjectNum(7)
										Bone:SetVelocity(Velocity + (ForceUp / 2) + ForceForward + (Superman and vector_origin or ForceRight))
										Bone = Ragdoll:GetPhysicsObjectNum(6)
										Bone:SetVelocity(Velocity + (ForceUp / 2) + (ForceForward / 2) + (Superman and vector_origin or ForceRight))

										Bone = Ragdoll:GetPhysicsObjectNum(12)
										Bone:SetVelocity(Velocity + (ForceUp / 2) - (ForceForward / 5) - (ForceRight / 5))
										Bone = Ragdoll:GetPhysicsObjectNum(9)
										Bone:SetVelocity(Velocity + (ForceUp / 2) - (ForceForward / 5) + (ForceRight / 5))
									end
								end
							end
						end
					end
				else
					if rm.RagdolizeOnSpeedEnabled:GetBool() and Ply:GetVelocity():Length() >= rm.RagdolizeOnSpeedValue:GetFloat() then
						rm.PlayerPlaySound(Ply, "FreeFall")
						Ply.rm_RecoveryTimer = rm.RagdollRecoveryDelayOnFall:GetFloat()
						Ragdoll = rm.PlayerRagdolize(Ply)
						if IsValid(Ragdoll) then
							rm.RagdollTwitch(Ragdoll, 900)
						end
					end
				end
				if rm.SoundEnabled:GetBool() then
					Ply.rm_SoundTimer = Ply.rm_SoundTimer + rm_Tick
				end
				if rm.RagdollMoveEnabled:GetBool() then
					Ply.rm_MoveTimer = Ply.rm_MoveTimer + rm_Tick
				end
				if rm.RagdollRecoveryEnabled:GetBool() and rm.RagdollRecoveryDelayEnabled:GetBool() then
					Ply.rm_RecoveryTimer = Ply.rm_RecoveryTimer - rm_Tick
					Ply:SetNetworkedInt("rm_RecoveryTimer", Ply.rm_RecoveryTimer)
				else
					Ply:SetNetworkedInt("rm_RecoveryTimer", 0)
				end
				if rm.OxygenEnabled:GetBool() then
					Ply:SetNetworkedFloat("rm_Oxygen", 1 - (Ply.rm_Oxygen / rm.OxygenValue:GetFloat()))
				else
					Ply:SetNetworkedFloat("rm_Oxygen", 1)
				end
			end
		end
	end)
	hook.Add("CreateEntityRagdoll", "rm_sv_BlockNPCRagdolls", function(Ent, Ragdoll)
		if rm.Enabled:GetBool() then
			if IsValid(Ent) and Ent:IsNPC() and rm.NPCRagdolizeOnDeathEnabled:GetBool() then
				Ragdoll:Remove()
			end
		end
	end)
	hook.Add("EntityTakeDamage", "rm_sv_Damage", function(Ent, Info)
		if rm.Enabled:GetBool() then
			if rm.NPCRagdolizeOnDeathEnabled:GetBool() and Ent:IsNPC() then
				Ent.rm_DamageInfo = Info
			else
				local Ply = nil
				local Vehicle = nil
				local Ragdoll = nil
				local IsLimb = false
				if Info:GetAmmoType() == 18 then
					Info:SetDamage(GetConVarNumber("sk_jeep_gauss_damage"))
				end
				if Info:GetAmmoType() == 20 then
					Info:SetDamage(GetConVarNumber("sk_plr_dmg_airboat"))
				end
				local Attacker = Info:GetAttacker()
				local Inflictor = Info:GetInflictor()
				local Amount = Info:GetDamage()
				if Ent:IsPlayer() then
					Ply = Ent
				elseif Ent:IsVehicle() then
					Vehicle = Ent
					Ply = Vehicle:GetDriver()
				elseif Ent:GetClass() == "prop_ragdoll" then
					if Ent.rm_IsRagdoll then
						Ragdoll = Ent
						IsLimb = Ent.rm_IsLimb or false
						if not IsLimb then
							local Owner = Ent.rm_Owner
							if IsValid(Owner) and Owner:IsPlayer() then
								if Owner.rm_Ragdoll == Ent then
									Ply = Owner
								end
							end
						end
					end
				end
				Ply = IsValid(Ply) and Ply or nil
				Vehicle = IsValid(Vehicle) and Vehicle or nil
				Ragdoll = IsValid(Ragdoll) and Ragdoll or nil
				if Ply ~= nil or Ragdoll ~= nil then
					if Info:GetDamagePosition() == vector_origin then
						Info:SetDamagePosition((IsLimb and Ragdoll:GetPhysicsObjectNum(Ragdoll.rm_LimbIndex):GetPos() or (Ragdoll or Ply):GetPos()) + (VectorRand() * (IsLimb and 5 or 20)))
					end
					if not IsValid(Attacker) then
						Attacker = game.GetWorld()
						if IsValid(Inflictor) then
							if Inflictor:IsPlayer() or Inflictor:IsNPC() then
								Attacker = Inflictor
							elseif Inflictor:IsVehicle() then
								Attacker = Inflictor:GetDriver()
							elseif IsValid(Inflictor:GetOwner()) then
								Attacker = Inflictor:GetOwner()
							elseif IsValid(Inflictor.rm_Owner) then
								Attacker = Inflictor.rm_Owner
							elseif IsValid(Inflictor.Owner) then
								Attacker = Inflictor.Owner
							end
						end
					end
					if not IsValid(Inflictor) or (Inflictor == Attacker and (Attacker:IsPlayer() or Attacker:IsNPC())) then
						Inflictor = game.GetWorld()
						if Attacker:IsPlayer() or Attacker:IsNPC() then
							local Weapon = Attacker:GetActiveWeapon()
							if IsValid(Weapon) then
								Inflictor = Weapon
							end
						end
					end
					if Ply then
						if IsValid(Attacker) or not IsValid(Ply.rm_Attacker) then
							Ply.rm_Attacker = Attacker
						end
						if IsValid(Inflictor) or not IsValid(Ply.rm_Inflictor) then
							Ply.rm_Inflictor = Inflictor
						end
					end
					local DamageMultiplier = rm.RagdollDamageMultiplier:GetFloat()
					if Ragdoll then
						if not IsValid(Attacker) then
							DamageMultiplier = DamageMultiplier / math.Rand(7.5, 25)
						elseif Inflictor:IsPlayer() or Inflictor.rm_IsRagdoll then
							DamageMultiplier = DamageMultiplier / math.Rand(75, 250)
						end
					end
					if Ply then
						if GetConVar("sbox_godmode"):GetBool() or (Attacker:IsPlayer() and Attacker ~= Ply and (not rm.RagdollDamagePVPEnabled:GetBool() or not GetConVar("sbox_playershurtplayers"):GetBool())) then
							DamageMultiplier = 0
						elseif not Ragdoll then
							DamageMultiplier = 1
							if (rm.RagdolizeOnDamageEnabled:GetBool() and Amount >= rm.RagdolizeOnDamageValue:GetFloat()) or (rm.RagdolizeOnFallEnabled:GetBool() and Info:IsFallDamage()) then
								if Info:IsExplosionDamage() then
									Ply.rm_RecoveryTimer = rm.RagdollRecoveryDelayOnExplosion:GetFloat()
								elseif Attacker:IsPlayer() or Attacker:IsNPC() then
									Ply.rm_RecoveryTimer = rm.RagdollRecoveryDelayOnPlayer:GetFloat()
								else
									Ply.rm_RecoveryTimer = rm.RagdollRecoveryDelayDefault:GetFloat()
								end
								Ragdoll = rm.PlayerRagdolize(Ply)
							end
						end
					end
					Amount = Amount * DamageMultiplier
					if Ply and Ply.rm_Alive then
						if rm.RagdollDamageEnabled:GetBool() and ((not Vehicle and Ragdoll) or (Vehicle and Vehicle:GetClass() == "prop_vehicle_prisoner_pod")) then
							Ply:SetHealth(math.max(Ply:Health() - Amount, 0))
						end
						if Ply:Health() <= 0 then
							Ply.rm_Alive = false
							local _, TargetIndex = nil, nil
							if Ragdoll then
								_, TargetIndex = rm.RagdollClosestBone(Ragdoll, Info:GetDamagePosition())
							else
								TargetIndex = rm.ModelClosestBone(Ply, Info:GetDamagePosition())
								TargetIndex = Ent:TranslateBoneToPhysBone(TargetIndex)
							end
							if rm.WeaponDropOnDeathEnabled:GetBool() then
								rm.PlayerDropActiveWeapon(Ply, false)
							end
							local HeadBone = Ply:LookupBone("ValveBiped.Bip01_Head1")
							if HeadBone then
								umsg.Start("rm_IndexDeath")
								umsg.Bool(TargetIndex == Ply:TranslateBoneToPhysBone(HeadBone))
								umsg.End()
							end
							Ply:Kill()
							if not Ragdoll then
								Ragdoll = IsValid(Ply.rm_Ragdoll) and Ply.rm_Ragdoll or nil
							end
							if Ragdoll then
								if Inflictor:GetClass() == "entityflame" then
									Ragdoll:Ignite(math.Rand(120, 240))
								end
							end
						elseif Amount > math.Rand(0.5, 5) then
							rm.PlayerPlaySound(Ply, "Pain")
						end
					end
					if Inflictor:GetClass() == "entityflame" then
						if Ragdoll and Ply and Ply.rm_Alive then
							rm.PlayerPlaySound(Ply, "PlayerBurn")
							rm.RagdollTwitch(Ragdoll, 125)
						end
						if not (Ragdoll or Ply):IsOnFire() and math.random(1, 10) == 1 then
							(Ragdoll or Ply):Ignite(math.Rand(30, 60))
						end
					end
					if Ragdoll and Amount > 0 then
						if Info:IsExplosionDamage() and rm.RagdollBurnOnExplosionEnabled:GetBool() and math.random(1, math.max(rm.RagdollBurnOnExplosionValue:GetFloat(), 1)) == 1 then
							Ragdoll:Ignite(math.Rand(30, 120))
						end
						if rm.RagdollBloodEnabled:GetBool() and Amount > math.Rand(0, 3) then
							local Pos = Info:GetDamagePosition()
							local Normal = Info:GetDamageForce():GetNormalized()
							if Amount >= math.Rand(8, 35) then
								rm.PlaySound(Ragdoll, "FleshSquish")
								util.Decal("Blood", Pos + Normal, Pos - Normal)
								util.Decal("Blood", Pos - Normal, Pos + Normal)
							end
							local Blood = EffectData()
							Blood:SetOrigin(Pos)
							Blood:SetNormal(-Normal)
							util.Effect("BloodImpact", Blood)
							if math.random(1, 15) == 1 then
								local Trace = util.TraceLine(
									{
										start = Pos,
										endpos = Pos + Vector(0, 0, 50),
										filter = {Ragdoll, Ply},
										mask = MASK_SOLID
									}
								)
								if Trace.HitWorld and Trace.HitNormal.z < -0.8 then
									local BloodDrip = EffectData()
									BloodDrip:SetOrigin(Trace.HitPos)
									util.Effect("rm_BloodDrip", BloodDrip)
								end
							end
							if rm.WeaponCrossbowWeldEnabled:GetBool() and Inflictor:GetClass() == "crossbow_bolt" and (not Ply or (Ply and not Ply.rm_Alive)) then
								local Trace = util.TraceLine(
									{
										start = Pos,
										endpos = Pos + (Normal * 50),
										filter = {Ragdoll, Inflictor, Ragdoll.rm_Owner},
										mask = MASK_SOLID
									}
								)
								if Trace.Hit and (IsValid(Trace.Entity) or Trace.Entity:IsWorld()) then
									local Target, TargetIndex = rm.RagdollClosestBone(Ragdoll, Info:GetDamagePosition())
									if Target then
										Ragdoll:EmitSound("weapons/crossbow/bolt_skewer1.wav", 100, math.Rand(90, 110) * ((GetConVar("host_timescale"):GetFloat() + 1) / 2))
										local TracePos = Trace.HitPos + (Target:GetPos() - Info:GetDamagePosition()) + (Trace.HitNormal * 8)
										if Target:GetPos():Distance(TracePos) > 8 then
											Target:SetPos(TracePos)
										end
										if Trace.HitWorld and Target:IsMotionEnabled() then
											Target:EnableMotion(false)
										else
											constraint.Weld(Trace.Entity, Ragdoll, Trace.PhysicsBone, TargetIndex, 10000, false)
										end
									end
								end
							end
						end
						if rm.RagdollTwitchEnabled:GetBool() and rm.RagdollTwitchOnDamageEnabled:GetBool() then
							if Inflictor.rm_IsRagdoll then
								rm.RagdollTwitch(Ragdoll, math.min(Amount / math.Rand(5, 25), 100))
							else
								if Ply and Ply.rm_Alive then
									rm.RagdollTwitch(Ragdoll, math.min(Amount * 25 * rm.RagdollTwitchOnDamageMultiplier:GetFloat(), 200))
								else
									rm.RagdollTwitch(Ragdoll, math.min(Amount / math.Rand(2, 5), 100))
								end
								local Target, TargetIndex = rm.RagdollClosestBone(Ragdoll, Info:GetDamagePosition())
								if not Inflictor:IsWorld() then
									local Force = vector_origin
									local Type = rm.RagdollForceType:GetInt()
									if Type == 1 then
										Force = Info:GetDamageForce() * (Info:IsExplosionDamage() and rm.RagdollForceMultiplierExplosion:GetFloat() or rm.RagdollForceMultiplier:GetFloat())
									elseif Type == 2 then
										Force = Info:GetDamageForce():GetNormalized() * (Info:IsExplosionDamage() and (math.Rand(5, 10) * rm.RagdollForceMultiplierExplosion:GetFloat()) or (math.Rand(40, 60) * rm.RagdollForceMultiplier:GetFloat())) * math.min(Amount / 3, 500)
									end
									if Info:IsExplosionDamage() and not IsLimb and Type == 1 then
										Ragdoll:GetPhysicsObject(0):AddVelocity(Force)
									elseif Target and not Info:IsExplosionDamage() then
										Target:AddVelocity(Force)
									elseif not IsLimb then
										rm.RagdollIterateBones(Ragdoll, function(Bone)
											Bone:AddVelocity(Force)
										end)
									end
								elseif not IsLimb and Target and rm.RagdollBounceEnabled:GetBool() and TargetIndex ~= 0 and TargetIndex ~= 1 then
									local Velocity = Target:GetVelocity()
									Target:AddVelocity((Vector(-Velocity.x, -Velocity.y, -Velocity.z / math.Rand(1.5, 3)) / math.Rand(25, 40) + (Vector(0, 0, Target:GetVelocity():Length() * math.Rand(1, 1.5) * math.min(Amount / math.Rand(3, 5), 40)))) * rm.RagdollBounceMultiplier:GetFloat())
								end
							end
						end
						if not Ply and Ragdoll:IsOnFire() and rm.RagdollBurnEnabled:GetBool() then
							local RagdollColor = Ragdoll:GetColor()
							local r, g, b = RagdollColor.r, RagdollColor.g, RagdollColor.b
							if r <= 40 then
								r = 40
							else
								r = r - 2
							end
							if g <= 40 then
								g = 40
							else
								g = g - 2
							end
							if b <= 40 then
								b = 40
							else
								b = b - 2
							end
							Ragdoll:SetColor(Color(r, g, b))
						end
						if (not Ply or (Ply and not Ply.rm_Alive)) then
							if Inflictor:GetClass() == "env_entity_dissolver" or Inflictor:GetClass() == "prop_combine_ball" or Inflictor:GetClass() == "hunter_flechette" then
								if Ply then
									Ply:Extinguish()
									rm.PlayerRemoveRagdollVariables(Ply)
								end
								rm.RagdollRemove(Ragdoll, 3)
								Ragdoll:SetGravity(0)
								rm.RagdollIterateBones(Ragdoll, function(Bone)
									Bone:SetVelocity((Info:GetDamageForce() * math.Rand(0, 0.01)) + Vector(0, 0, math.Rand(0, 50)))
									Bone:EnableGravity(false)
									Bone:EnableCollisions(false)
									Bone:EnableDrag(false)
									Bone:SetMass(1)
								end)
								if Inflictor:GetClass() ~= "env_entity_dissolver" then
									local Dissolver = ents.Create("env_entity_dissolver")
									Dissolver.Target = "rm_Dissolver" ..Dissolver:EntIndex()
									Dissolver:SetKeyValue("DissolveType", 0)
									Dissolver:SetKeyValue("Magnitude", 100)
									Dissolver:SetPos(Ragdoll:GetPos())
									Dissolver:Spawn()
									Ragdoll:SetName(Dissolver.Target)
									Dissolver:Fire("Dissolve", Dissolver.Target)
									Dissolver:Remove()
								end
							end
							if not IsLimb and Inflictor:GetClass() ~= "crossbow_bolt" and Inflictor:GetClass() ~= "weapon_pistol" then
								if (Amount >= rm.RagdollDecapitationValue:GetFloat() and rm.RagdollDecapitationEnabled:GetBool()) or (Amount >= rm.RagdollGibValue:GetFloat() and rm.RagdollGibEnabled:GetBool()) then
									local Gib = Amount >= rm.RagdollGibValue:GetFloat()
									for x = 1, (Info:IsExplosionDamage() and math.ceil(Amount / (Gib and math.Rand(5, 15) or math.Rand(3, 9))) or 1) do
										if not IsValid(Ragdoll) or not Ragdoll.rm_IsRagdoll then
											break
										end
										local Target, TargetIndex, TargetChild, TargetChildIndex = rm.RagdollClosestBone(Ragdoll, Info:GetDamagePosition(), true)
										local ForceDecapitation = true
										for i = 1, Ragdoll:GetPhysicsObjectCount() do
											if not Ragdoll["rm_DecapitatedBone" ..i] then
												ForceDecapitation = false
												break
											end
										end
										if not Target or ForceDecapitation then
											rm.PlaySound(Ragdoll, "FleshBreak")
											if Gib then
												if rm.RagdollBloodEnabled:GetBool() then
													local Effect = EffectData()
													Effect:SetOrigin(Ragdoll:GetPos())
													Effect:SetNormal(Info:GetDamageForce():GetNormalized())
													util.Effect("rm_TorsoGib", Effect)
													for i = 1, math.random(6, 8) do
														local Spurt = EffectData()
														Spurt:SetOrigin(Ragdoll:GetPos() + (VectorRand() * 15))
														Spurt:SetScale(math.Rand(8, 10))
														Spurt:SetNormal(Info:GetDamageForce():GetNormalized() + (VectorRand():GetNormalized() / 10))
														Spurt:SetMagnitude(math.Rand(75, 250))
														util.Effect("rm_BloodSpurt", Spurt)
													end
												end
												Ragdoll:Remove()
												break
											end
										elseif not Ragdoll["rm_DecapitatedBone" ..TargetIndex] and (not IsValid(TargetChild) or Ragdoll["rm_DecapitatedBone" ..TargetChildIndex]) and Target:GetPos():Distance(Info:GetDamagePosition()) < (Info:IsExplosionDamage() and math.Rand(100, 300) or math.Rand(20, 30)) then
											rm.PlaySound(Ragdoll, "FleshBreak")
											Ragdoll["rm_DecapitatedBone" ..TargetIndex] = true
											Ragdoll:SetNetworkedBool("rm_DecapitatedBone" ..TargetIndex, true)
											rm.RagdollHideChildBones(Ragdoll, Ragdoll:TranslatePhysBoneToBone(TargetIndex))
											Target:EnableMotion(true)
											Target:EnableGravity(false)
											Target:EnableCollisions(false)
											Target:EnableDrag(false)
											Target:SetMass(1)
											if rm.RagdollBloodEnabled:GetBool() then
												local ModelBone = Ragdoll:TranslatePhysBoneToBone(TargetIndex)
												local Effect = EffectData()
												Effect:SetOrigin(Target:GetPos() + Target:GetMassCenter())
												Effect:SetNormal(Info:GetDamageForce():GetNormalized())
												if Gib then
													if ModelBone == Ragdoll:LookupBone("ValveBiped.Bip01_Head1") or ModelBone == Ragdoll:LookupBone("head") or ModelBone == Ragdoll:LookupBone("eyes") then
														util.Effect("rm_HeadGib", Effect)
													else
														util.Effect("rm_LimbGib", Effect)
													end
												else
													util.Effect("rm_LimbDecapitation", Effect)
												end
												local Spurt = EffectData()
												Spurt:SetEntity(Ragdoll)
												Spurt:SetAttachment(TargetIndex)
												if ModelBone == Ragdoll:LookupBone("ValveBiped.Bip01_Head1") or ModelBone == Ragdoll:LookupBone("head") or ModelBone == Ragdoll:LookupBone("eyes") then
													Spurt:SetScale(Gib and 5 or 3)
													Spurt:SetMagnitude(Gib and math.Rand(110, 130) or math.Rand(75, 90))
												else
													Spurt:SetScale(Gib and 3 or 2)
													Spurt:SetMagnitude(math.Rand(50, 90) or math.Rand(25, 50))
												end
												util.Effect("rm_BloodSpurt", Spurt)
											end
											if not Gib then
												local Limb = ents.Create("prop_ragdoll")
												Limb:SetModel(Ragdoll:GetModel())
												Limb:SetPos(Ragdoll:GetPos())
												Limb:SetAngles(Ragdoll:GetAngles())
												Limb:SetSkin(Ragdoll:GetSkin())
												Limb:SetMaterial(Ragdoll:GetMaterial())
												Limb:SetColor(Ragdoll:GetColor())
												Limb:SetPhysicsAttacker(Ply)
												Limb.rm_Owner = Ply
												Limb.rm_IsRagdoll = true
												Limb:SetNetworkedBool("rm_IsRagdoll", true)
												Limb.rm_IsLimb = true
												Limb:SetNetworkedBool("rm_IsLimb", true)
												Limb.rm_LimbIndex = TargetIndex
												Limb:SetNetworkedInt("rm_LimbIndex", TargetIndex)
												Limb.rm_IsUnderwater = Ragdoll.rm_IsUnderwater or false
												Limb:Spawn()
												rm.RagdollIterateBones(Limb, function(Bone, i)
													local RagdollBone = Ragdoll:GetPhysicsObjectNum(i)
													Bone:SetPos(RagdollBone:GetPos())
													Bone:SetAngles(RagdollBone:GetAngles())
													Bone:SetVelocity(RagdollBone:GetVelocity())
													if i ~= TargetIndex then
														Bone:EnableGravity(false)
														Bone:EnableCollisions(false)
														Bone:EnableDrag(false)
														Bone:SetMass(Bone:GetMass() / 10)
													else
														Bone:SetMass(Bone:GetMass() * 5)
													end
												end)
												if Ragdoll:IsOnFire() then
													Limb:Ignite(math.Rand(0, 30))
												end
												rm.ModelIterateBones(Limb, function(i)
													local BoneIndex = Limb:TranslateBoneToPhysBone(i)
													if BoneIndex ~= TargetIndex then
														Limb:ManipulateBoneScale(i, vector_origin)
														Limb:ManipulateBonePosition(i, vector_origin)
													end
												end)
												timer.Simple(math.Rand(30, 60), function()
													if IsValid(Limb) then
														rm.RagdollRemove(Limb)
													end
												end)
											end
										end
									end
								end
							elseif IsLimb and rm.RagdollGibEnabled:GetBool() and Amount >= rm.RagdollGibValue:GetFloat() then
								rm.PlaySound(Ragdoll, "FleshBreak")
								if rm.RagdollBloodEnabled:GetBool() then
									local Effect = EffectData()
									Effect:SetOrigin(Info:GetDamagePosition())
									Effect:SetNormal(Info:GetDamageForce():GetNormalized())
									util.Effect("rm_LimbGib", Effect)
								end
								Ragdoll:Remove()
							end
						end
					elseif Amount == 0 and Inflictor:GetClass() == "prop_combine_ball" then
						Inflictor:Fire("Explode")
					end
				end
			end
		end
	end)
	hook.Add("PlayerSpawn", "rm_sv_PlayerSpawn", rm.PlayerSpawn)
	hook.Add("CanPlayerSuicide", "rm_sv_PlayerSuicide", function(Ply)
		if rm.Enabled:GetBool() and rm.WeaponDropOnSuicideEnabled:GetBool() then
			rm.PlayerDropActiveWeapon(Ply, false)
		end
	end)
	hook.Add("PlayerDeathSound", "rm_sv_PlayerDeathSound", function()
		return rm.Enabled:GetBool() and true or nil
	end)
	hook.Add("PlayerDeath", "rm_sv_PlayerDeath", function(Ply, Inflictor, Attacker)
		if rm.Enabled:GetBool() then
			Ply.rm_Alive = false
			Ply.rm_WeaponPreserve = false
			Ply.DeathTime = CurTime()
			Ply.NextSpawnTime = Ply.DeathTime + rm.RespawnDelay:GetFloat()
			Ply:SetNetworkedFloat("rm_DeathTime", Ply.DeathTime)
			Ply:SetNetworkedFloat("rm_SpawnTime", Ply.NextSpawnTime)
			rm.PlayerPlaySound(Ply, "Death")
			if rm.RagdollDamageFixInfoEnabled:GetBool() then
				if not IsValid(Ply.rm_Attacker) and (Ply.rm_Attacker and not Ply.rm_Attacker:IsWorld()) then
					Ply.rm_Attacker = game.GetWorld()
					if IsValid(Attacker) then
						Ply.rm_Attacker = Attacker
					end
				end
				if not IsValid(Ply.rm_Inflictor) and (Ply.rm_Inflictor and not Ply.rm_Inflictor:IsWorld()) then
					Ply.rm_Inflictor = game.GetWorld()
					if IsValid(Inflictor) then
						Ply.rm_Inflictor = Inflictor
					end
				end
				if IsValid(Ply.rm_Attacker) then
					if Ply.rm_Attacker:IsPlayer() then
						if Ply.rm_Attacker == Ply then
							umsg.Start("PlayerKilledSelf")
							umsg.Entity(Ply)
							umsg.End()
							MsgAll(Ply:Nick().. " suicided!\n")
						else
							umsg.Start("PlayerKilledByPlayer")
							umsg.Entity(Ply)
							umsg.String(Ply.rm_Inflictor:GetClass())
							umsg.Entity(Ply.rm_Attacker)
							umsg.End()
							if IsValid(Ply.rm_Inflictor) and Ply.rm_Inflictor ~= Ply then
								MsgAll(Ply.rm_Attacker:Nick().. " killed " ..Ply:Nick().. " with " ..Ply.rm_Inflictor:GetClass().. "\n")
							else
								MsgAll(Ply.rm_Attacker:Nick().. " killed " ..Ply:Nick().. "\n")
							end
							Ply.rm_Attacker.rm_Kills = Ply.rm_Attacker.rm_Kills + 1
							Ply.rm_Attacker:SetNetworkedInt("rm_Kills", Ply.rm_Attacker.rm_Kills)
						end
					elseif Ply.rm_Attacker:IsNPC() then
						umsg.Start("PlayerKilled")
						umsg.Entity(Ply)
						umsg.String(Ply.rm_Inflictor:GetClass())
						umsg.String(Ply.rm_Attacker:GetClass())
						umsg.End()
						if IsValid(Ply.rm_Inflictor) and Ply.rm_Inflictor ~= Ply then
							MsgAll(Ply.rm_Attacker:GetClass().. " killed " ..Ply:Nick().. " with " ..Ply.rm_Inflictor:GetClass().. "\n")
						else
							MsgAll(Ply.rm_Attacker:GetClass().. " killed " ..Ply:Nick().. "\n")
						end
					else
						umsg.Start("PlayerKilled")
						umsg.Entity(Ply)
						umsg.String(Ply.rm_Inflictor:GetClass())
						umsg.String(Ply.rm_Attacker:GetClass())
						umsg.End()
						MsgAll(Ply:Nick().. " was killed by " ..Ply.rm_Attacker:GetClass().. "\n")
					end
				else
					umsg.Start("PlayerKilledSelf")
					umsg.Entity(Ply)
					umsg.End()
					Ply:AddFrags(1)
					MsgAll(Ply:Nick() .. " died!\n")
				end
			end
			if IsValid(Ply.rm_Attacker) and (Ply.rm_Attacker:IsPlayer() or Ply.rm_Attacker:IsNPC()) and Ply.rm_Attacker ~= Ply then
				Ply:SetNetworkedEntity("rm_Killer", Ply.rm_Attacker)
			end
			if rm.RagdolizeOnDeathEnabled:GetBool() then
				local Ragdoll = Ply:GetRagdollEntity()
				if IsValid(Ragdoll) then
					Ragdoll:Remove()
				end
				Ragdoll = Ply.rm_Ragdoll or rm.PlayerRagdolize(Ply, true)
				if IsValid(Ragdoll) then
					rm.RagdollDeath(Ragdoll)
				end
				for i, Item in pairs(Ply.rm_Ragdolls) do
					if not IsValid(Item) then
						table.remove(Ply.rm_Ragdolls, i)
					end
				end
				table.insert(Ply.rm_Ragdolls, Ply.rm_Ragdoll)
				if rm.RagdollKeepEnabled:GetBool() then
					if rm.RagdollKeepPlayerValue:GetInt() > 0 then
						if #Ply.rm_Ragdolls > rm.RagdollKeepPlayerValue:GetInt() then
							rm.RagdollRemove(Ply.rm_Ragdolls[1])
							table.remove(Ply.rm_Ragdolls, 1)
						end
					end
				end
			else
				rm.PlayerRemoveRagdoll(Ply)
				Ply:SetNetworkedEntity("rm_Ragdoll", Ply:GetRagdollEntity())
			end
			return rm.RagdollDamageFixInfoEnabled:GetBool() or nil
		end
	end)
	hook.Add("OnNPCKilled", "rm_sv_NPCDeath", function(NPC, Ent)
		if rm.Enabled:GetBool() then
			if IsValid(Ent) then
				if Ent:IsPlayer() then
					Ent.rm_Kills = Ent.rm_Kills + 1
					Ent:SetNetworkedInt("rm_Kills", Ent.rm_Kills)
					Ent:AddFrags(1)
					MsgAll(Ent:Nick().. " killed " ..NPC:GetClass() .. (IsValid(Ent:GetActiveWeapon()) and " with " ..Ent:GetActiveWeapon():GetClass() or "").. "\n")
				elseif Ent:IsNPC() then
					MsgAll(Ent:GetClass().. " killed " ..NPC:GetClass() .. (IsValid(Ent:GetActiveWeapon()) and " with " ..Ent:GetActiveWeapon():GetClass() or "").. "\n")
				else
					MsgAll(NPC:GetClass().. " was killed by " ..Ent:GetClass().. "\n")
				end
			else
				MsgAll(NPC:GetClass().. " died!\n")
			end
			if GetConVar("ai_serverragdolls"):GetBool() and rm.NPCRagdolizeOnDeathEnabled:GetBool() then
				local Ragdoll = rm.NPCRagdolize(NPC)
				if IsValid(Ragdoll) then
					if NPC.rm_DamageInfo then
						local _, TargetIndex = rm.RagdollClosestBone(Ragdoll, NPC.rm_DamageInfo:GetDamagePosition())
						umsg.Start("rm_IndexDeath")
						local BoneIndex = Ragdoll:LookupBone("ValveBiped.Bip01_Head1") or Ragdoll:LookupBone("head") or Ragdoll:LookupBone("eyes")
						if BoneIndex then
							umsg.Bool(TargetIndex == Ragdoll:TranslateBoneToPhysBone(BoneIndex))
						else
							umsg.Bool(false)
						end
						umsg.End()
					else
						umsg.Start("rm_IndexDeath")
						umsg.Bool(false)
						umsg.End()
					end
					rm.RagdollDeath(Ragdoll)
				end
			end
		end
	end)
	hook.Add("CanPlayerEnterVehicle", "rm_sv_VehicleBlock", function(Ply, Ent)
		if rm.Enabled:GetBool() and Ply.rm_Ragdoll then
			return false
		end
	end)
	hook.Add("PlayerLeaveVehicle", "rm_sv_PlayerLeaveVehicle", function(Ply, Ent)
		if rm.Enabled:GetBool() and rm.RagdolizeOnEjectEnabled:GetBool() and not Ply.rm_Ragdoll and not Ply.rm_ExitingVehicle then
			if Ent:GetVelocity():Length() >= rm.RagdolizeOnEjectValue:GetInt() then
				Ply.rm_RecoveryTimer = rm.RagdollRecoveryDelayOnEject:GetFloat()
				Ply.rm_ExitingVehicle = true
				local Ragdoll = rm.PlayerRagdolize(Ply)
				Ply.rm_ExitingVehicle = false
				if IsValid(Ragdoll) then
					rm.RagdollIterateBones(Ragdoll, function(Bone)
						Bone:SetVelocity((Ent:GetVelocity() * 1.2) + (VectorRand() * 10))
					end)
					rm.PlayerPlaySound(Ply, "FreeFall")
				end
			end
		end
	end)
	hook.Add("PlayerDisconnected", "rm_sv_PlayerDisconnected", function(Ply)
		if rm.Enabled:GetBool() then
			rm.PlayerRemoveRagdoll(Ply)
			for _, Item in pairs(ents.GetAll()) do
				if IsValid(Item) and Item.rm_IsRagdoll and Item.rm_Owner == Ply then
					rm.RagdollRemove(Item)
				end
			end
		end
	end)
	hook.Add("KeyPress", "rm_sv_KeyPress", function(Ply, Key)
		if rm.Enabled:GetBool() and Ply.rm_Alive then
			if Key == IN_JUMP or Key == IN_ATTACK or Key == IN_ATTACK2 then
				Ply.rm_Parachute = false
				rm.PlayerRecover(Ply)
			elseif Key == IN_FORWARD then
				Ply.rm_Move = true
			elseif Key == IN_BACK then
				Ply.rm_Twitch = true
			elseif Key == IN_RELOAD then
				Ply.rm_WeaponLowered = false
				rm.PlayerRecover(Ply, true)
			end
		end
	end)
	hook.Add("KeyRelease", "rm_sv_KeyRelease", function(Ply, Key)
		if rm.Enabled:GetBool() and Ply.rm_Alive then
			if Key == IN_FORWARD then
				Ply.rm_Move = false
			elseif Key == IN_BACK then
				Ply.rm_Twitch = false
			end
		end
	end)
	hook.Add("CanTool", "rm_sv_BlockToolGun", function(Ply, Trace, Mode)
		local Ent = Trace.Entity
		if rm.Enabled:GetBool() and IsValid(Ent) and Ent.rm_IsRagdoll then
			local Owner = Ent.rm_Owner
			if IsValid(Owner) and Owner:IsPlayer() and Owner.rm_Ragdoll == Ent then
				if not rm.RagdollToolGunEnabled:GetBool() or Mode == "remover" then
					return false
				end
				Ent.rm_Attacker = Ply
				Ent.rm_Inflictor = Ply:GetActiveWeapon()
			end
		end
	end)
	hook.Add("PhysgunPickup", "rm_sv_BlockPhysGun", function(Ply, Ent)
		if rm.Enabled:GetBool() and IsValid(Ent) and Ent.rm_IsRagdoll then
			local Owner = Ent.rm_Owner
			if IsValid(Owner) and Owner:IsPlayer() and Owner.rm_Ragdoll == Ent then
				if rm.RagdollPhysGunEnabled:GetBool() then
					return false
				end
				Ent.rm_Attacker = Ply
				Ent.rm_Inflictor = Ply:GetActiveWeapon()
			end
		end
	end)
	concommand.Add("rm_version", function(Ply, Command, Args)
		Ply:PrintMessage(HUD_PRINTCONSOLE, "RagMod 2 version " ..rm.Version.. "\n")
	end)
	concommand.Add("rm_ragdolize", function(Ply, Command, Args)
		if rm.Enabled:GetBool() and rm.RagdolizeOnCommandEnabled:GetBool() and IsValid(Ply) and Ply:IsPlayer() and not IsValid(Ply.rm_Ragdoll) then
			Ply.rm_RecoveryTimer = rm.RagdollRecoveryDelayDefault:GetFloat()
			rm.PlayerRagdolize(Ply)
		end
	end)
	concommand.Add("rm_ragdolize_target", function(Ply, Command, Args)
		if rm.Enabled:GetBool() and IsValid(Ply) and Ply:IsPlayer() and Ply:IsAdmin() then
			for _, Arg in pairs(Args) do
				if Arg ~= nil then
					for _, Ply in pairs(player.GetAll()) do
						if string.find(string.lower(Ply:Nick()), string.lower(Arg)) then
							MsgAll("[RagMod] " ..Ply:Nick().. " ragdolized " ..Ply:Nick().. ".\n")
							if IsValid(Ply.rm_Ragdoll) then
								rm.PlayerRecoverSpawn(Ply)
							else
								Ply.rm_RecoveryTimer = rm.RagdollRecoveryDelayDefault:GetFloat()
								rm.PlayerRagdolize(Ply)
							end
						end
					end
				end
			end
		end
	end)
	concommand.Add("rm_recover_target", function(Ply, Command, Args)
		if rm.Enabled:GetBool() and IsValid(Ply) and Ply:IsPlayer() and Ply:IsAdmin() then
			for _, Arg in pairs(Args) do
				if Arg ~= nil then
					for _, Ply in pairs(player.GetAll()) do
						if string.find(string.lower(Ply:Nick()), string.lower(Arg)) and Ply.rm_Ragdoll then
							MsgAll("[RagMod] " ..Ply:Nick().. " reset " ..Ply:Nick().. ".\n")
							rm.PlayerRecoverSpawn(Ply, false, true)
						end
					end
				end
			end
		end
	end)
	concommand.Add("rm_reset", function(Ply, Command, Args)
		if rm.Enabled:GetBool() and IsValid(Ply) and Ply:IsPlayer() then
			rm.PlayerRecover(Ply, true)
		end
	end)
	concommand.Add("rm_reset_target", function(Ply, Command, Args)
		if rm.Enabled:GetBool() and IsValid(Ply) and Ply:IsPlayer() and Ply:IsAdmin() then
			for _, Arg in pairs(Args) do
				if Arg ~= nil then
					for _, Ply in pairs(player.GetAll()) do
						if string.find(string.lower(Ply:Nick()), string.lower(Arg)) then
							MsgAll("[RagMod] " ..Ply:Nick().. " reset " ..Ply:Nick().. ".\n")
							rm.PlayerRecoverSpawn(Ply, true, true)
						end
					end
				end
			end
		end
	end)
	concommand.Add("rm_grab", function(Ply, Command, Args)
		if rm.Enabled:GetBool() and rm.RagdollGrabOnCommandEnabled:GetBool() and IsValid(Ply) and Ply:IsPlayer() then
			rm.PlayerGrab(Ply)
		end
	end)
	concommand.Add("rm_grab_target", function(Ply, Command, Args)
		if rm.Enabled:GetBool() and IsValid(Ply) and Ply:IsPlayer() and Ply:IsAdmin() then
			for _, Arg in pairs(Args) do
				if Arg ~= nil then
					for _, Ply in pairs(player.GetAll()) do
						if string.find(string.lower(Ply:Nick()), string.lower(Arg)) then
							MsgAll("[RagMod] " ..Ply:Nick().. " grabbed " ..Ply:Nick().. ".\n")
							rm.PlayerGrab(Ply)
						end
					end
				end
			end
		end
	end)
	concommand.Add("rm_parachute", function(Ply, Command, Args)
		if rm.Enabled:GetBool() and rm.RagdollParachuteOnCommandEnabled:GetBool() and IsValid(Ply) and Ply:IsPlayer() then
			if Ply.rm_Parachute then
				Ply.rm_Parachute = false
			else
				if (function()
					if rm.RagdollParachuteOnCommandUnlimitedEnabled:GetBool() then
						return true
					elseif Ply:HasWeapon("swep_parachute") then
						return true
					elseif Ply.rm_Ragdoll then
						for _, Weapon in pairs(Ply.rm_WeaponClass) do
							if Weapon == "swep_parachute" then
								return true
							end
						end
					end
					return false
				end)() then
					rm.PlayerParachute(Ply)
				end
			end
		end
	end)
	concommand.Add("rm_parachute_target", function(Ply, Command, Args)
		if rm.Enabled:GetBool() and IsValid(Ply) and Ply:IsPlayer() and Ply:IsAdmin() then
			for _, Arg in pairs(Args) do
				if Arg ~= nil then
					for _, Ply in pairs(player.GetAll()) do
						if string.find(string.lower(Ply:Nick()), string.lower(Arg)) then
							MsgAll("[RagMod] " ..Ply:Nick().. " parachuted " ..Ply:Nick().. ".\n")
							if Ply.rm_Parachute then
								Ply.rm_Parachute = false
							else
								rm.PlayerParachute(Ply)
							end
						end
					end
				end
			end
		end
	end)
	concommand.Add("rm_lowerweapon", function(Ply, Command, Args)
		local Weapon = Ply:GetActiveWeapon()
		if rm.Enabled:GetBool() and Ply.rm_Alive and not Ply.rm_Ragdoll and IsValid(Weapon) then
			if Ply.rm_WeaponLowered then
				Ply.rm_WeaponLowered = false
			else
				Ply.rm_WeaponLowered = true
				Weapon:SetNextPrimaryFire(1000000)
				Weapon:SetNextSecondaryFire(1000000)
				umsg.Start("rm_lowerweapon")
				umsg.Entity(Weapon)
				umsg.Bool(true)
				umsg.End()
				local function Check()
					timer.Simple(FrameTime(), function()
						if IsValid(Ply) then
							if Ply.rm_Ragdoll or not Ply.rm_WeaponLowered or not IsValid(Ply:GetActiveWeapon()) or not IsValid(Weapon) or Ply:GetActiveWeapon() ~= Weapon then
								if IsValid(Weapon) then
									Weapon:SetNextPrimaryFire(0)
									Weapon:SetNextSecondaryFire(0)
									umsg.Start("rm_lowerweapon")
									umsg.Entity(Weapon)
									umsg.Bool(false)
									umsg.Bool(not (Ply:GetActiveWeapon() == Weapon))
									umsg.End()
								end
								Ply.rm_WeaponLowered = false
								return
							end
						end
						Check()
					end)
				end
				Check()
			end
		end
	end)
	concommand.Add("rm_holsterweapon", function(Ply, Command, Args)
		if rm.Enabled:GetBool() and Ply.rm_Alive and not Ply.rm_Ragdoll then
			local Weapon = Ply:GetActiveWeapon()
			if Ply.rm_WeaponSelected ~= "" and not IsValid(Weapon) then
				Ply:SelectWeapon(Ply.rm_WeaponSelected)
				Ply.rm_WeaponSelected = ""
				Weapon = Ply:GetActiveWeapon()
				Weapon:SendWeaponAnim(ACT_VM_DRAW)
				timer.Simple(1, function()
					if Ply:GetActiveWeapon() == Weapon then
						Weapon:SendWeaponAnim(ACT_VM_IDLE)
						Weapon:SetNextPrimaryFire(CurTime())
						Weapon:SetNextSecondaryFire(CurTime())
					end
				end)
			elseif IsValid(Weapon) then
				Weapon:SendWeaponAnim(ACT_VM_HOLSTER)
				timer.Simple(FrameTime(), function()
					if IsValid(Weapon) and Ply:GetActiveWeapon() == Weapon then
						Ply.rm_WeaponSelected = Weapon:GetClass()
						Ply:SetActiveWeapon(NULL)
						Ply:DrawViewModel(false)
					end
				end)
			end
		end
	end)
	concommand.Add("rm_dropammo", function(Ply, Command, Args)
		local Weapon = Ply:GetActiveWeapon()
		if rm.Enabled:GetBool() and Ply.rm_Alive and not Ply.rm_Ragdoll and IsValid(Weapon) then
			local Class = nil
			if Args[1] == "1" then
				local Primary = Weapon:GetPrimaryAmmoType()
				local Count = 0
				if Primary == 1 then
					if Ply:GetAmmoCount(Weapon:GetPrimaryAmmoType()) >= 100 then
						Count = 100
						Class = "item_ammo_ar2_large" --item_large_box_lrounds
					else
						Count = 20
						Class = "item_ammo_ar2" --item_box_lrounds
					end
				elseif Primary == 3 then
					if Ply:GetAmmoCount(Weapon:GetPrimaryAmmoType()) >= 100 then
						Count = 100
						Class = "item_ammo_pistol_large" --item_large_box_srounds
					else
						Count = 20
						Class = "item_ammo_pistol" --item_box_srounds
					end
				elseif Primary == 4 then
					if Ply:GetAmmoCount(Weapon:GetPrimaryAmmoType()) >= 225 then
						Count = 225
						Class = "item_ammo_smg1_large" --item_large_box_mrounds
					else
						Count = 45
						Class = "item_ammo_smg1" --item_box_mrounds
					end
				elseif Primary == 5 then
					if Ply:GetAmmoCount(Weapon:GetPrimaryAmmoType()) >= 20 then
						Count = 20
						Class = "item_ammo_357_large"
					else
						Count = 6
						Class = "item_ammo_357"
					end
				elseif Primary == 6 then
					Count = 6
					Class = "item_ammo_crossbow"
				elseif Primary == 7 then
					Count = 20
					Class = "item_box_buckshot"
				elseif Primary == 8 then
					Count = 1
					Class = "item_rpg_round" --item_ml_grenade
				elseif Primary == 10 then
					Count = 1
					Class = "weapon_frag"
				else
					return
				end
				if Ply:GetAmmoCount(Weapon:GetPrimaryAmmoType()) >= Count then
					Ply:RemoveAmmo(Count, Weapon:GetPrimaryAmmoType())
				else
					return
				end
			elseif Args[1] == "2" then
				local Secondary = Weapon:GetSecondaryAmmoType()
				local Count = 0
				if Secondary == 2 then
					Count = 1
					Class = "item_ammo_ar2_altfire"
				elseif Secondary == 9 then
					Count = 1
					Class = "item_ammo_smg1_grenade" --item_ar2_grenade
				else
					return
				end
				if Ply:GetAmmoCount(Weapon:GetSecondaryAmmoType()) >= Count then
					Ply:RemoveAmmo(Count, Weapon:GetSecondaryAmmoType())
				else
					return
				end
			else
				return
			end
			local Ammo = ents.Create(Class)
			Ammo:Spawn()
			local Trace = util.TraceLine(
				{
					start = Ply:EyePos(),
					endpos = Ply:EyePos() + (Ply:GetAimVector() * 150),
					filter = Ply
				}
			)
			if Trace.Hit then
				Ammo:SetPos(Trace.HitPos + Vector(0, 0, 12))
				Ammo:SetAngles(Ply:GetAngles() + Angle(0, 180, 0))
			else
				Ammo:SetPos(Ply:EyePos() + (Ply:GetAimVector() * 100))
				Ammo:SetAngles(Ply:EyeAngles())
				Ammo:GetPhysicsObject():SetVelocity(Ply:GetVelocity() + (Ply:GetAimVector() * 500))
			end
		end
	end)
	concommand.Add("rm_dropweapon", function(Ply, Command, Args)
		if rm.Enabled:GetBool() then
			rm.PlayerDropActiveWeapon(Ply, true)
		end
	end)
	for _, Ply in pairs(player.GetAll()) do
		Ply.rm_Ready = false
		rm.PlayerSpawn(Ply)
	end
end

if CLIENT then
	local Incursion = 0
	local function LoadClientLua()
		if not IsValid(LocalPlayer()) then
			Incursion = Incursion + 1
			Msg("[RagMod] Client load check #" ..Incursion.. ", returned " ..tostring(LocalPlayer()).. ".\n")
			timer.Simple(FrameTime(), LoadClientLua)
		else
			local EntityMetaTable = FindMetaTable("Entity")
			if EntityMetaTable then
				function EntityMetaTable:GetRagdollOwner()
					if CLIENT then
						if self:GetNetworkedBool("rm_IsRagdoll") then
							local Owner = self:GetNetworkedEntity("rm_Owner")
							if IsValid(Owner) then
								return Owner
							end
						end
					elseif SERVER then
						if self.rm_IsRagdoll then
							local Owner = self.rm_Owner
							if IsValid(Owner) then
								return Owner
							end
						end
					else
						return self:GetOwner()
					end
				end
			end
			local rm_HeadshotTable = {}
			local rm_HeadshotTexture = surface.GetTextureID("HUD/killicons/headshot")
			local rm_HeadshotIndex = 0
			local rm_HeadshotY = -1
			local rm_Heartbeat = CreateSound(LocalPlayer(), file.Exists("sound/RagMod/Heartbeat.wav", "GAME") and Sound("RagMod/Heartbeat.wav") or Sound("player/heartbeat1.wav"))
			rm_Heartbeat:Play()
			rm_Heartbeat:ChangePitch(0, 0)
			rm_Heartbeat:ChangeVolume(0, 0)
			local rm_Wind = CreateSound(LocalPlayer(), Sound("ambient/wind/wind1.wav"))
			rm_Wind:Play()
			rm_Wind:ChangePitch(0, 0)
			rm_Wind:ChangeVolume(0, 0)
			local rm_WindHit1 = CreateSound(LocalPlayer(), Sound("ambient/wind/wind_hit1.wav"))
			rm_WindHit1:Play()
			rm_WindHit1:ChangePitch(0, 0)
			rm_WindHit1:ChangeVolume(0, 0)
			local rm_WindHit2 = CreateSound(LocalPlayer(), Sound("ambient/wind/wind_hit2.wav"))
			rm_WindHit2:Play()
			rm_WindHit2:ChangePitch(0, 0)
			rm_WindHit2:ChangeVolume(0, 0)
			local rm_WindHit3 = CreateSound(LocalPlayer(), Sound("ambient/wind/wind_hit3.wav"))
			rm_WindHit3:Play()
			rm_WindHit3:ChangePitch(0, 0)
			rm_WindHit3:ChangeVolume(0, 0)
			surface.CreateFont("rm_UI",
				{
					font = "Coolvetica",
					size = 24,
					weight = 300,
					blursize = 0,
					scanlines = 0,
					antialias = 1,
					underline = false,
					italic = false,
					strikeout = false,
					symbol = false,
					rotary = false,
					shadow = false,
					additive = false,
					outline = true
				}
			)
			for Class, Name in pairs(
				{
					["combine_mine"] = "Combine Mine",
					["entityflame"] = "Fire",
					["env_explosion"] = "Explosion",
					["func_button"] = "Button",
					["func_train"] = "Vehicle",
					["func_tracktrain"] = "Vehicle",
					["func_tank"] = "Turret",
					["gmod_balloon"] = "Balloon",
					["grenade_hand"] = "Assassain",
					["HL2_Annabelle"] = "Annabelle",
					["item_ammo_crate"] = "Ammunition Crate",
					["nihilanth_energy_ball"] = "Nihilanth",
					["npc_clawscanner"] = "Claw Scanner",
					["npc_helicopter"] = "Combine Helicopter",
					["prop_dynamic"] = "Prop",
					["trigger_hurt"] = "Terrain",
					["weapon_357"] = "Revolver",
					["weapon_annabelle"] = "Annabelle",
					["weapon_ar2"] = "AR2",
					["weapon_crowbar"] = "Crowbar",
					["weapon_crossbow"] = "Crossbow",
					["weapon_frag"] = "Grenade",
					["weapon_physcannon"] = "Gravity Gun",
					["weapon_physgun"] = "Physics Gun",
					["weapon_pistol"] = "Pistol",
					["weapon_rpg"] = "RPG",
					["weapon_shotgun"] = "Shotgun",
					["weapon_smg1"] = "SMG",
					["weapon_striderbuster"] = "Magnusson Device",
					["World"] = "Terrain",
					["worldspawn"] = "Terrain"
				}
			) do
				language.Add(Class, Name)
			end
			if killicon then
				killicon.Add("entityflame", "HUD/killicons/entityflame", Color(255, 80, 0, 255))
				killicon.Add("player", "HUD/killicons/player", Color(255, 80, 0, 255))
				killicon.Add("prop_ragdoll", "HUD/killicons/prop_ragdoll", Color(255, 80, 0, 255))
				killicon.Add("weapon_physcannon", "HUD/killicons/weapon_physcannon", Color(255, 80, 0, 255))
				killicon.AddAlias("gmod_turret", "weapon_smg1")
				killicon.AddAlias("grenade_hand", "weapon_grenade")
				killicon.AddAlias("prop_dynamic", "prop_physics")
				killicon.AddAlias("weapon_crossbow", "crossbow_bolt")
				killicon.AddAlias("weapon_rpg", "rpg_missile")
				killicon.AddAlias("weapon_physgun", "weapon_physcannon")
				if not killicon.DrawOld then
					killicon.DrawOld = killicon.Draw
				end
				function killicon.Draw(x, y, Name, Alpha)
					if y > rm_HeadshotY then
						rm_HeadshotIndex = rm_HeadshotIndex + 1
					elseif y < rm_HeadshotY then
						rm_HeadshotIndex = 1
					end
					rm_HeadshotY = y
					if rm.HeadshotEnabled:GetBool() and rm.HeadshotClientEnabled:GetBool() then
						local Time = CurTime()
						local Data = nil
						while true do
							Data = rm_HeadshotTable[rm_HeadshotIndex]
							if not Data then break end
							if Data.DieTime < Time then
								table.remove(rm_HeadshotTable, rm_HeadshotIndex)
							else
								break
							end
						end
						if Data then
							if Data.IsHeadshot then
								local Width, Height = killicon.GetSize(Name)
								surface.SetTexture(rm_HeadshotTexture)
								surface.SetDrawColor(255, 80, 0, Alpha)
								surface.DrawTexturedRect(x + (Width / 2) - 15, y - (Height / 2) + ((Height - 16) / 2), 32, 32)
								killicon.DrawOld(x - 15, y, Name, Alpha)
								return
							end
						end
					end
					killicon.DrawOld(x, y, Name, Alpha)
				end
			end
			usermessage.Hook("rm_IndexDeath", function(Data)
				local IsHeadshot = Data:ReadBool()
				if IsHeadshot and rm.HeadshotEnabled:GetBool() and rm.HeadshotClientEnabled:GetBool() and rm.HeadshotSoundEnabled:GetBool() then
					GetViewEntity():EmitSound("RagMod/Headshot.wav", 100, 100 * ((GetConVar("host_timescale"):GetFloat() + 1) / 2))
				end
				if killicon then
					table.insert(rm_HeadshotTable, {IsHeadshot = IsHeadshot, DieTime = CurTime() + GetConVar("hud_deathnotice_time"):GetFloat()})
				end
			end)
			usermessage.Hook("rm_lowerweapon", function(Data)
				local Weapon = Data:ReadEntity()
				if IsValid(Weapon) then
					local Holster = Data:ReadBool()
					local CancelAnimations = Data:ReadBool()
					if Holster then
						if not CancelAnimations then
							Weapon:SendWeaponAnim(ACT_VM_IDLE_LOWERED)
						end
						if Weapon.SetWeaponHoldType then
							Weapon:SetWeaponHoldType("passive")
							Weapon.HoldType = Weapon.HoldType or Weapon:GetHoldType()
						end
					else
						if not CancelAnimations then
							Weapon:SendWeaponAnim(ACT_VM_IDLE)
						end
						if Weapon.SetWeaponHoldType then
							Weapon:SetWeaponHoldType(
								(function()
									if Weapon:GetClass() == "gmod_tool" then
										return "pistol"
									elseif Weapon:GetClass() == "gmod_camera" then
										return "camera"
									elseif Weapon.HoldType then
										return Weapon.HoldType
									else
										return "normal"
									end
								end)()
							)
						end
					end
				end
			end)
			concommand.Add("rm_help", function(Ply, Command, Args)
				local Help = [[

/// Welcome, to... /////////////////////////////////////////
//                                                        //
//                                                        //
//  ======    =====    ======   =====    =====   ======   //
//  ==   ==  ==   ==  ==       == = ==  ==   ==  ==   ==  //
//  ======   =======  ==  ===  == = ==  ==   ==  ==   ==  //
//  == ==    ==   ==  ==   ==  == = ==  ==   ==  ==   ==  //
//  ==   ==  ==   ==  ======   == = ==   =====   ======   //
//                                                        //
//    ======       ==   ==  =======  ======    =======    //
//         ==      ==   ==  ==       ==   ==   ==         //
//       ==         == ==   =====    ======    ======     //
//     ==            ===    ==       == ==          ==    //
//    =======         =     =======  ==   ==   ======     //
//                                                        //
//                                                        //
/// About: RagMod 2 ////////////////////////////////////////
//                                                        //
//                                                        //
// Thank you for choosing RagMod 2 version 5!             //
//                                                        //
// This version includes cleaned-up console variables,    //
//     many fixes, and new features! The addon is also    //
//     faster, with less redundancy in the ragdolization  //
//     generation functions and other code.               //
//                                                        //
// This version is the next iteration of RagMod 2 version //
//     4.x, which was an unofficial edit of version 3b,   //
//     which, in itself, was an unofficial edit of        //
//     version 3. RagMod was originally created by        //
//     DayStranger3, better known as ds3. You can find    //
//     the original release thread for version 3 here:    //
//     http://facepunch.com/threads/718151                //
//                                                        //
// Please contact DarkShadow6 if you have any questions.  //
//     Steam: dark_shadow_6                               //
//                                                        //
// P.S.: DayStranger3 released a public beta for a newer  //
//     edition of RagMod, 3, which included many of the   //
//     features you see here. I, however, started off     //
//     using RagMod 2 v3b as a base instead. RagMod 3 was //
//     built much differently than 2 v3b, and as a direct //
//     result, was slower and buggier. If you know of a   //
//     feature that RagMod 3 (or any other addon, for     //
//     that matter) has that this version doesn't, don't  //
//     hesitate to say so; I'll try my best to impliment  //
//     it in a later version!                             //
//                                                        //
// Enjoy!                                                 //
//                                                        //
//                                                        //
/// Introduction: What is RagMod 2? ////////////////////////
//                                                        //
//                                                        //
// RagMod 2 is a quickly-growing addon for Garry's Mod    //
//     that morphs your player into a ragdoll when you    //
//     take a lot of damage, fall a height, go too fast,  //
//     etc. All of these values can also be customized    //
//     with the many console variables that exist; it     //
//     supports NPC ragdolization upon them being         //
//     killed, and it even works in multiplayer!          //
// RagMod 2 also features a few neat SWEPs as a bonus,    //
//     including a rope used for climbing while           //
//     ragdolized, and a small usable parachute!          //
// RagMod 2 has a large array of console commands related //
//     to ragdolizing, recovery, and weapons, along with  //
//     other miscellaneous commands.                      //
//                                                        //
//                                                        //
/// Instructions: What do I do? ////////////////////////////
//                                                        //
//                                                        //
// To become a ragdoll, just use the rm_ragdolize console //
//     command. RagMod 2 also automatically ragdolizes    //
//     you upon reaching certain prerequisites (such as   //
//     damage, falling and speed, as stated above). All   //
//     of these values can be changed via console, listed //
//     under the heading "rm_" for proper orginization.   //
//                                                        //
// For those unaccustomed to using the console, all of    //
//     the console commands RagMod 2 uses are also        //
//     activatable via button in the RagMod 2 menu. If    //
//     you would like to use the console instead, all     //
//     commands are also listed below.                    //
//                                                        //
// Console commands:                                      //
//  ////////////////////////////////////////////////////  //
//  // Command                                 Action //  //
//  ////////////////////////////////////////////////////  //
//  // rm_ragdolize                  Become a ragdoll //  //
//  // rm_reset                Reset while ragdolized //  //
//  // rm_grab                       See grab section //  //
//  // rm_parachute             See parachute section //  //
//  // rm_lowerweapon               Lower your weapon //  //
//  // rm_holsterweapon           Holster your weapon //  //
//  // rm_dropammo 1                Drop primary ammo //  //
//  // rm_dropammo 2              Drop secondary ammo //  //
//  // rm_dropweapon                 Drop your weapon //  //
//  ////////////////////////////////////////////////////  //
//                                                        //
//                                                        //
/// Instructions: Controlling your body ////////////////////
//                                                        //
//                                                        //
// RagMod 2 features an intuitive control system that     //
//     gives you full control over your RagMod ragdoll.   //
//                                                        //
// Basic controls:                                        //
//  ////////////////////////////////////////////////////  //
//  // Key                  Ground action  Air action //  //
//  ////////////////////////////////////////////////////  //
//  // Attack 1 / 2, Jump         Recover   No action //  //
//  // Forwards                Crawl/Swim  Glide/Dive //  //
//  // Backwards                   Twitch   No change //  //
//  // Reload      Reset while ragdolized   No change //  //
//  ////////////////////////////////////////////////////  //
//                                                        //
//                                                        //
/// Instructions: Grab /////////////////////////////////////
//                                                        //
//                                                        //
// Upon using the grab command, you will be ragdolized    //
//     with your feet welded to the ground. You will hold //
//     your arms out, attempting to remain steady. This   //
//     tactic is very useful in situations where staying  //
//     attached to one place without much effort is a     //
//     must. If you are grabbing something and use grab   //
//     again, you will be unwelded. You can instantly     //
//     recover while grabbing an object.                  //
//                                                        //
//                                                        //
/// Instructions: Parachute ////////////////////////////////
//                                                        //
//                                                        //
// Use the parachute command if you have a parachute in   //
//     your inventory to use it whenever you like, not    //
//     just with the SWep. You can also use the parachute //
//     command again to unhook yourself from your         //
//     parachute at any time it is deployed.              //
//                                                        //
// Parachute-specific controls:                           //
//  ////////////////////////////////////////////////////  //
//  // Title / Key                             Action //  //
//  ////////////////////////////////////////////////////  //
//  // Attack 1 / 2, Jump           Release parachute //  //
//  // Forwards                          Fly forwards //  //
//  ////////////////////////////////////////////////////  //
//                                                        //
//                                                        //
/// Tips ///////////////////////////////////////////////////
//                                                        //
//                                                        //
// If you don't want to open the console to ragdolize or  //
//     change settings, remember that there is a RagMod 2 //
//     menu under the "Options" tab of the spawn menu.    //
//     But you knew that already, right?                  //
//                                                        //
// Try binding a key to rm_ragdolize to ragdolize         //
//     whenever you press the bound button:               //
//         bind <key> rm_ragdolize                        //
//     This works for all the other commands, too.        //
//                                                        //
// You can use the Climb Rope to rope yourself to objects //
//     to keep yourself from falling off. Surprisingly,   //
//     it's not really that good for climbing... Grab can //
//     be used as an alternative, though it's harder to   //
//     stay upright. You also don't move around as much.  //
//     Use grab for low-speed situations, and the Climb   //
//     Rope for higher speeds.                            //
//                                                        //
// When swimming, movement isn't restricted to left and   //
//     right. You can swim up and down, too! Use this to  //
//     your advantage. You can also instantly recover     //
//     while swimming.                                    //
//                                                        //
// When gliding, look all the way down while holding      //
//     forward to dive. It makes you fall at top speed in //
//     a nosedive! Just make to level out before it's too //
//     late to change your mind...                        //
//                                                        //
//                                                        //
/// Thanks /////////////////////////////////////////////////
//                                                        //
//                                                        //
// I want to thank Hentie for their help getting me past  //
//     a few roadblocks in the decapitation code and for  //
//     helping me impliment the Climb Rope SWep more      //
//     efficiently. Couldn't have done it without you.    //
//                                                        //
// I also want to thank the nice portion of the Facepunch //
//     community in general for helping me out with my    //
//     addmittedly shoddy Garry's Mod Lua skills,         //
//     reporting bugs, and otherwise being good people.   //
//     (Well, usually.)                                   //
//                                                        //
// I would also like to thank Kirk for helping out with   //
//     beta testing and some Lua help. Thanks, buddy.     //
//                                                        //
// Finally, I would like to thank some of my Steam and    //
//     real-life friends for giving some (mostly) useful  //
//     tips on what I could do to make RagMod 2 better.   //
//                                                        //
//                                                        //
////////////////////////////////////////////////////////////

]]
				local i = 1
				local function ShowHelp()
					Msg(string.sub(Help, i, i + 60))
					i = i + 61
					if i > string.len(Help) then
						return
					end
					ShowHelp()
				end
				ShowHelp()
			end)
			--[[ Old BBP code, kept just in case Garry brings it back.
			hook.Add("OnEntityCreated", "rm_cl_DecapitationHandler", function(Ent)
				if IsValid(Ent) and Ent:GetClass() == "prop_ragdoll" then
					local Old = Ent.BuildBonePositions
					local function New(Ent, Bones, PhysBones)
						if Ent:GetNetworkedBool("rm_IsLimb") then
							local LimbIndex = Ent:GetNetworkedInt("rm_LimbIndex")
							local LimbMatrix = Ent:GetBoneMatrix(Ent:TranslatePhysBoneToBone(LimbIndex))
							if LimbMatrix then
								rm.ModelIterateBones(Ent, function(i)
									local BoneIndex = Ent:TranslateBoneToPhysBone(i)
									if BoneIndex ~= LimbIndex then
										local BoneMatrix = Ent:GetBoneMatrix(i)
										if BoneMatrix then
											BoneMatrix:Translate(Ent:GetPhysicsObjectNum(BoneIndex):WorldToLocal(LimbMatrix:GetTranslation()))
											BoneMatrix:Scale(vector_origin)
											BoneMatrix:Rotate(vector_origin)
											Ent:SetBoneMatrix(i, BoneMatrix)
										end
									end
								end)
							end
						else
							rm.ModelIterateBones(Ent, function(i)
								if Ent:GetNetworkedBool("rm_DecapitatedBone" ..Ent:TranslateBoneToPhysBone(i)) then
									local BoneMatrix = Ent:GetBoneMatrix(i)
									if BoneMatrix then
										BoneMatrix:Translate(vector_origin)
										BoneMatrix:Scale(vector_origin)
										BoneMatrix:Rotate(Angle(0, 0, 0))
										Ent:SetBoneMatrix(i, BoneMatrix)
									end
								end
							end)
						end
					end
					if Old then
						function Ent.BuildBonePositions(...)
							Old(...)
							New(...)
						end
					else
						Ent.BuildBonePositions = New
					end
					print(Old, New)
				end
			end)
			--]]
			hook.Add("PlayerFootstep", "rm_cl_PlayerFootstep", function(Ply, Pos, Foot, SoundPath, Volume, Filter)
				if rm.Enabled:GetBool() and IsValid(Ply:GetNetworkedEntity("rm_Ragdoll")) then
					return true
				end
			end)
			hook.Add("CalcView", "rm_cl_CalcView", function(Ply, Origin, Angles, Fov)
				if GetViewEntity() == Ply and rm.Enabled:GetBool() then
					local Mode = rm.AfterdeathCameraMode:GetInt()
					local Killer = Ply:GetNetworkedEntity("rm_Killer")
					if Mode > 0 and Mode < 4 and IsValid(Killer) and rm.AfterdeathEnabled:GetBool() and rm.AfterdeathClientEnabled:GetBool() then
						Killer = IsValid(Killer:GetNetworkedEntity("rm_Ragdoll")) and Killer:GetNetworkedEntity("rm_Ragdoll") or Killer
						local KillerPos = IsValid(Killer:GetPhysicsObject()) and (Killer:GetPhysicsObject():GetMassCenter() + Vector(0, 0, 5)) or (Killer:GetPos() + Vector(0, 0, 50))
						local PlyPos = (IsValid(Ply:GetNetworkedEntity("rm_Ragdoll")) and Ply:GetNetworkedEntity("rm_Ragdoll") or Ply):GetPos() + Vector(0, 0, 30)
						if Mode == 1 and (Killer:IsPlayer() or Killer:IsNPC()) then
							local Eyes = Killer:GetAttachment(Killer:LookupAttachment("eyes")) or Killer:GetAttachment(Killer:LookupAttachment("anim_attachment_head")) or Killer:GetAttachment(Killer:LookupAttachment("head"))
							local Origin = nil
							local Angles = nil
							if Eyes then
								Origin = Eyes.Pos
								Angles = Eyes.Ang
							else
								if Killer:GetClass() == "npc_barnacle" then
									Origin = Killer:LocalToWorld(Vector(100, 0, 0))
									Angles = Killer:GetAngles() + Angle(-90, 0, 0)
								else
									Origin = Killer:LocalToWorld(Vector(-150, 0, 100))
									Angles = Killer:GetAngles()
								end
							end
							return {origin = Origin, angles = Angles, fov = Fov}
						elseif Mode == 2 then
							return {origin = PlyPos, angles = (KillerPos - PlyPos):Angle(), fov = Fov}
						elseif Mode == 3 then
							return {origin = KillerPos, angles = (PlyPos - KillerPos):Angle(), fov = Fov}
						end
					else
						local Ragdoll = Ply:GetNetworkedEntity("rm_Ragdoll")
						if IsValid(Ragdoll) then
							local Mode = rm.RagdollCameraMode:GetInt()
							if Mode == 1 or Mode == 2 then
								local Eyes = Ragdoll:GetAttachment(Ragdoll:LookupAttachment("eyes"))
								return {origin = Eyes.Pos + Vector(0, 0, 2), angles = (function()
									if Mode == 1 then
										return Ply:EyeAngles()
									elseif Mode == 2 then
										return Eyes.Ang
									end
								end)(), fov = Fov}
							end
						end
					end
				end
			end)
			hook.Add("RenderScreenspaceEffects", "rm_cl_Effects", function()
				local PlyLocal = LocalPlayer()
				local Ragdoll = PlyLocal:GetNetworkedEntity("rm_Ragdoll")
				Ragdoll = IsValid(Ragdoll) and Ragdoll
				if rm.Enabled:GetBool() then
					if not rm.SoundWindEnabled:GetBool() then
						rm_Wind:ChangePitch(0, 0)
						rm_Wind:ChangeVolume(0, 0)
					elseif not rm.SoundWindRestrict:GetBool() or (rm.SoundWindRestrict:GetBool() and Ragdoll) then
						local Speed = (Ragdoll or PlyLocal):GetVelocity():Length()
						rm_Wind:ChangePitch(math.Clamp(100 + (Speed / 15), 0, 255), 0.25)
						rm_Wind:ChangeVolume(1 - math.cos(math.Clamp(Speed / 1500, 0, math.pi / 2)), 0.1)
						local Chance = 1 / (Speed / 45000)
						if Chance < 100 then
							if math.random(0, math.max(math.ceil(Chance, 40))) == 0 then
								local Sound = math.random(1, 3)
								if Sound == 1 then
									Sound = rm_WindHit1
								elseif Sound == 2 then
									Sound = rm_WindHit2
								elseif Sound == 3 then
									Sound = rm_WindHit3
								end
								Sound:ChangePitch(math.Clamp(150 + (Speed / 25), 0, 255), 0.25)
								Sound:ChangeVolume(math.Clamp(1 - math.cos(math.Clamp(Speed / 1250, 0, math.pi / 2)), 0, 1), 0.25)
								timer.Simple(0.25, function()
									Sound:ChangePitch(100, math.Rand(1, 2.3))
									Sound:ChangeVolume(0, math.Rand(1, 2.3))
								end)
							end
						end
					end
					if GetViewEntity() == PlyLocal then
						local Multiplier = math.cos(math.cos(math.Clamp(1 - (PlyLocal:Health() / 100), 0, 1) * (math.pi / 2)) * (math.pi / 2))
						if not rm.SoundHeartbeatEnabled:GetBool() then
							rm_Heartbeat:ChangePitch(0, 0)
							rm_Heartbeat:ChangeVolume(0, 0)
						elseif PlyLocal:Alive() then
							rm_Heartbeat:ChangePitch(((1 - Multiplier) * 80) + (Multiplier * 150) + math.Rand(-5, 5), 0)
							rm_Heartbeat:ChangeVolume(Multiplier, 0)
						else
							rm_Heartbeat:ChangePitch(math.Rand(0.4, 0.7), 0)
							rm_Heartbeat:ChangeVolume(1, 0)
						end
						if rm.PPEnabled:GetBool() then
							if rm.PPRestrict:GetBool() then
								Multiplier = PlyLocal:Alive() and 0 or 1
							end
							if Multiplier > 0 then
								DrawColorModify(
									{
										["$pp_colour_addr"] = rm.PPAddR:GetFloat() * Multiplier,
										["$pp_colour_addg"] = rm.PPAddG:GetFloat() * Multiplier,
										["$pp_colour_addb"] = rm.PPAddB:GetFloat() * Multiplier,
										["$pp_colour_brightness"] = (rm.PPBrightness:GetFloat() - 1) * Multiplier,
										["$pp_colour_contrast"] = (1 - Multiplier) + (rm.PPContrast:GetFloat() * Multiplier),
										["$pp_colour_colour"] = (1 - Multiplier) + (rm.PPColor:GetFloat() * Multiplier),
										["$pp_colour_mulr"] = (rm.PPMulR:GetFloat() - 1) * Multiplier,
										["$pp_colour_mulg"] = (rm.PPMulG:GetFloat() - 1) * Multiplier,
										["$pp_colour_mulb"] = (rm.PPMulB:GetFloat() - 1) * Multiplier
									}
								)
								DrawMotionBlur((1 - Multiplier) + (rm.PPBlurAlpha:GetFloat() * Multiplier), 0.99, 0)
							end
						end
					else
						rm_Heartbeat:ChangePitch(0, 0)
						rm_Heartbeat:ChangeVolume(0, 0)
					end
				end
			end)
			hook.Add("GetMotionBlurValues", "rm_cl_MotionBlur", function(x, y, Forward, Spin, ...)
				local PlyLocal = LocalPlayer()
				if rm.Enabled:GetBool() and GetViewEntity() == PlyLocal and rm.PPEnabled:GetBool() and rm.PPMotionBlurEnabled:GetBool() and ((rm.PPMotionBlurRestrict:GetBool() and Ragdoll) or not Ragdoll) then
					local Ragdoll = PlyLocal:GetNetworkedEntity("rm_Ragdoll")
					Ragdoll = IsValid(Ragdoll) and Ragdoll
					local Velocity = (Ragdoll or PlyLocal):GetVelocity():Angle()
					local Angles = (Ragdoll or PlyLocal):GetAngles()
					local Speed = math.min((Ragdoll or PlyLocal):GetVelocity():Length() / 80000, 1)
					local x2 = math.sin(math.AngleDifference(Velocity.y, Angles.y) / 360) * 4
					local y2 = math.sin(math.AngleDifference(Velocity.p, Angles.p) / 360) * 4
					if x2 > 1 then
						x2 = 1 - (x2 - 1)
					elseif x2 < -1 then
						x2 = -1 - (x2 + 1)
					end
					if y2 > 1 then
						y2 = 1 - (y2 - 1)
					elseif y2 < -1 then
						y2 = -1 - (y2 + 1)
					end
					local Multiplier = rm.PPMotionBlurScale:GetFloat()
					x = x + x2 * Speed * Multiplier
					y = y + y2 * Speed * Multiplier
					Forward = Forward + Speed * Multiplier
					return x, y, Forward, Spin
				end
			end)
			hook.Add("HUDPaint", "rm_cl_HUDPaint", function()
				if rm.Enabled:GetBool() then
					local PlyLocal = LocalPlayer()
					if PlyLocal:Alive() then
						local PosX, PosY, SizeX, SizeY = ScrW() / 2, ScrH() - 70, 400, 25
						local RecoveryTimer = math.ceil(PlyLocal:GetNetworkedInt("rm_RecoveryTimer"))
						if RecoveryTimer > 0 and rm.RagdollRecoveryHUDEnabled:GetBool() and IsValid(PlyLocal:GetNetworkedEntity("rm_Ragdoll")) then
							surface.SetDrawColor(0, 0, 0, 127.5)
							surface.DrawRect(PosX - SizeX / 2, PosY, SizeX, SizeY)
							draw.DrawText("You have to wait " ..tostring(RecoveryTimer).. " " ..(RecoveryTimer == 1 and "second" or "seconds").. " to recover", "rm_UI", PosX, PosY, Color(255, 255, 255, 255), 1)
							PosY = PosY + SizeY
						end
						local Oxygen = PlyLocal:GetNetworkedFloat("rm_Oxygen")
						if Oxygen < 1 and rm.OxygenHUDEnabled:GetBool() then
							surface.SetDrawColor(0, 0, 0, 127.5)
							surface.DrawRect(PosX - SizeX / 2, PosY, SizeX, SizeY)
							if rm.OxygenHUDBarEnabled:GetBool() then
								surface.SetDrawColor(255, 255 * Oxygen, 255 * Oxygen, 127.5)
								surface.DrawRect(PosX - SizeX / 2 + 5, PosY + 5, SizeX * Oxygen - 10, SizeY - 10)
							end
							if rm.OxygenHUDTextEnabled:GetBool() then
								draw.DrawText(Oxygen <= 0 and "Drowning!" or "Oxygen", "rm_UI", PosX, PosY, Color(255, 255 * Oxygen, 255 * Oxygen, 255), 1)
							end
							PosY = PosY + SizeY
						end
					else
						if rm.AfterdeathEnabled:GetBool() and rm.AfterdeathClientEnabled:GetBool() and rm.AfterdeathHUDEnabled:GetBool() then
							local Width = ScrW()
							local Height = ScrH()
							local Size = 0
							local Text = nil
							surface.SetDrawColor(0, 0, 0, 255)
							if rm.AfterdeathHUDRespawnTimeEnabled:GetBool() then
								Size = Size + 20
								surface.DrawRect(0, Height - Size, Width, 20)
								Text = "Respawn in: "
								if not surface.GetTextSize(Text) then
									return
								end
								draw.DrawText(Text, "rm_UI", (Width - surface.GetTextSize(Text)) / 2, Height - Size, Color(255, 255, 255), 1)
								local Time = CurTime()
								local SpawnTime = PlyLocal:GetNetworkedFloat("rm_SpawnTime")
								local DeathTime = PlyLocal:GetNetworkedFloat("rm_DeathTime")
								Text = string.sub(tostring(math.max(SpawnTime - Time, 0)), 1, 5)
								if Text == "0" then
									Text = "0 seconds"
								else
									Text = Text .. string.rep("0", math.max(0, 4 - string.len(Text))) .. " seconds"
								end
								draw.DrawText(Text, "rm_UI", (Width + surface.GetTextSize(Text)) / 2, Height - Size, Color(255, 0, 0), 1)
							end
							if rm.AfterdeathHUDKillsEnabled:GetBool() then
								Size = Size + 20
								surface.DrawRect(0, Height - Size, Width, 20)
								Text = "Total kills: "
								draw.DrawText(Text, "rm_UI", (Width - surface.GetTextSize(Text)) / 2, Height - Size, Color(255, 255, 255), 1)
								Text = tostring(PlyLocal:GetNetworkedInt("rm_Kills"))
								draw.DrawText(Text, "rm_UI", (Width + surface.GetTextSize(Text)) / 2, Height - Size, Color(255, 0, 0), 1)
							end
							local Killer = PlyLocal:GetNetworkedEntity("rm_Killer")
							if IsValid(Killer) and rm.AfterdeathHUDKillerEnabled:GetBool() then
								Size = Size + 20
								surface.DrawRect(0, Height - Size, Width, 20)
								Text = "Killed by: "
								draw.DrawText(Text, "rm_UI", (Width - surface.GetTextSize(Text)) / 2, Height - Size, Color(255, 255, 255), 1)
								if Killer:IsPlayer() then
									Text = Killer:Nick()
								else
									Text = "#" ..Killer:GetClass():lower()
								end
								draw.DrawText(Text, "rm_UI", (Width + surface.GetTextSize(Text)) / 2, Height - Size, Color(255, 0, 0), 1)
							end
							if Size == 0 then
								Size = 20
								surface.DrawRect(0, Height - Size, Width, 20)
							end
							surface.DrawRect(0, 0, Width, Size)
							draw.DrawText("Afterdeath", "rm_UI", Width / 2, (Size - 20) / 2, Color(255, 255, 255), 1)
						end
					end
				end
			end)
			hook.Add("PhysgunPickup", "rm_cl_BlockPhysGun", function(Ply, Ent)
				if rm.Enabled:GetBool() and IsValid(Ent) and Ent:GetNetworkedBool("rm_IsRagdoll") then
					for _, Ply in pairs(player.GetAll()) do
						if Ply:GetNetworkedEntity("rm_Ragdoll") == Ent then
							if rm.RagdollPhysGunEnabled:GetBool() then
								return false
							end
						end
					end
				end
			end)
			hook.Add("Tick", "rm_cl_Tick", function()
				if rm.RagdollBurnDeflateEnabled:GetBool() then
					for _, Ragdoll in pairs(ents.FindByClass("prop_ragdoll")) do
						if Ragdoll:IsOnFire() then
							for i = 1, #rm.RagdollBurnDeflateData, 2 do
								if math.random(1, 25) == 1 then
									local Bone = Ragdoll:LookupBone(rm.RagdollBurnDeflateData[i])
									if Bone then
										local Size = Ragdoll:GetManipulateBoneScale(Bone)
										local x, y, z = Size.x, Size.y, Size.z
										if x > 0 and y > 0 and z > 0 then
											x = x - 0.001
											y = y - 0.001
											z = z - 0.001
											local MaxSize = rm.RagdollBurnDeflateData[i + 1]
											if x < MaxSize then
												x = MaxSize
											end
											if y < MaxSize then
												y = MaxSize
											end
											if z < MaxSize then
												z = MaxSize
											end
											Ragdoll:ManipulateBoneScale(Bone, Vector(x, y, z))
										end
									end
								end
							end
						end
					end
				end
			end)
		end
	end
	LoadClientLua()
end


hook.Add("PopulateToolMenu", "rm_PopulateToolMenu", function()
	spawnmenu.AddToolMenuOption("Options", "RagMod 2 " ..rm.Version, "RagModSettings", "Settings", "", "", function(CPanel)
		CPanel:AddControl("Label", {Text = "RagMod 2 " ..rm.Version.. " client commands and settings"})
		CPanel:AddControl("Label", {Text = "\n\nCommands\n"})
		CPanel:AddControl("Button", {Label = "Ragdolize (rm_ragdolize)", Command = "rm_ragdolize"})
		CPanel:AddControl("Button", {Label = "Grab (rm_grab)", Command = "rm_grab"})
		CPanel:AddControl("Button", {Label = "Parachute (rm_parachute)", Command = "rm_parachute"})
		CPanel:AddControl("Button", {Label = "Reset (rm_reset)", Command = "rm_reset"})
		CPanel:AddControl("Label", {Text = ""})
		CPanel:AddControl("Button", {Label = "Lower weapon (rm_lowerweapon)", Command = "rm_lowerweapon"})
		CPanel:AddControl("Button", {Label = "Holster weapon (rm_holsterweapon)", Command = "rm_holsterweapon"})
		CPanel:AddControl("Button", {Label = "Drop ammo (rm_dropammo 1)", Command = "rm_dropammo 1"})
		CPanel:AddControl("Button", {Label = "Drop secondary ammo (rm_dropammo 2)", Command = "rm_dropammo 2"})
		CPanel:AddControl("Button", {Label = "Drop weapon (rm_dropweapon)", Command = "rm_dropweapon"})
		CPanel:AddControl("Label", {Text = ""})
		CPanel:AddControl("Button", {Label = "Help (rm_help, opens in console)", Command = "showconsole;rm_help"})
		CPanel:AddControl("Label", {Text = "\n\nCamera\n"})
		CPanel:AddControl("ComboBox",
			{
				Label = "          Mode:",
				Options =
				{
					["Third-person"] = {rm_ragdoll_camera_mode = 0},
					["First-person"] = {rm_ragdoll_camera_mode = 1},
					["First-person (camera oriented to ragdoll)"] = {rm_ragdoll_camera_mode = 2}
				},
				CVars =
				{
					"rm_ragdoll_camera_mode"
				},
				MenuButton = "0",
				Folder = ""
			}
		)
		CPanel:AddControl("Label", {Text = "\n\nPost-processing\n"})
		CPanel:AddControl("CheckBox", {Label = "Enabled", Command = "rm_pp_enabled"})
		CPanel:AddControl("CheckBox", {Label = "Restrict to death", Command = "rm_pp_restrict"})
		CPanel:AddControl("ComboBox",
			{
				Label = "          Presets:",
				Options =
				{
					["Default"] =
					{
						rm_pp_addr = "0",
						rm_pp_addg = "0",
						rm_pp_addb = "0",
						rm_pp_brightness = "0.9",
						rm_pp_contrast = "1.3",
						rm_pp_color = "0.4",
						rm_pp_mulr = "1",
						rm_pp_mulg = "1",
						rm_pp_mulb = "1",
						rm_pp_bluralpha = "0.7"
					},
					["Minimal"] =
					{
						rm_pp_addr = "0",
						rm_pp_addg = "0",
						rm_pp_addb = "0",
						rm_pp_brightness = "1",
						rm_pp_contrast = "1.3",
						rm_pp_color = "0.8",
						rm_pp_mulr = "1",
						rm_pp_mulg = "1",
						rm_pp_mulb = "1",
						rm_pp_bluralpha = "0.8"
					},
					["Bright"] =
					{
						rm_pp_addr = "0",
						rm_pp_addg = "0",
						rm_pp_addb = "0",
						rm_pp_brightness = "1.5",
						rm_pp_contrast = "1.2",
						rm_pp_color = "0.9",
						rm_pp_mulr = "1",
						rm_pp_mulg = "1",
						rm_pp_mulb = "1",
						rm_pp_bluralpha = "0.8"
					},
					["Black and White"] =
					{
						rm_pp_addr = "0",
						rm_pp_addg = "0",
						rm_pp_addb = "0",
						rm_pp_brightness = "1.2",
						rm_pp_contrast = "1",
						rm_pp_color = "0",
						rm_pp_mulr = "1",
						rm_pp_mulg = "1",
						rm_pp_mulb = "1",
						rm_pp_bluralpha = "0.4"
					},
					["High-Contrast Black and White"] =
					{
						rm_pp_addr = "0",
						rm_pp_addg = "0",
						rm_pp_addb = "0",
						rm_pp_brightness = "0.5",
						rm_pp_contrast = "8",
						rm_pp_color = "0",
						rm_pp_mulr = "1",
						rm_pp_mulg = "1",
						rm_pp_mulb = "1",
						rm_pp_bluralpha = "0.25"
					},
					["Blurry"] =
					{
						rm_pp_addr = "0",
						rm_pp_addg = "0",
						rm_pp_addb = "0",
						rm_pp_brightness = "1.25",
						rm_pp_contrast = "0.8",
						rm_pp_color = "0.9",
						rm_pp_mulr = "1.1",
						rm_pp_mulg = "1.1",
						rm_pp_mulb = "1",
						rm_pp_bluralpha = "0.2"
					},
					["Gritty"] =
					{
						rm_pp_addr = "0",
						rm_pp_addg = "0",
						rm_pp_addb = "0",
						rm_pp_brightness = "0.7",
						rm_pp_contrast = "3",
						rm_pp_color = "0.3",
						rm_pp_mulr = "1",
						rm_pp_mulg = "1",
						rm_pp_mulb = "1",
						rm_pp_bluralpha = "0.65"
					},
					["Half-Life Red"] =
					{
						rm_pp_addr = "0.4",
						rm_pp_addg = "0",
						rm_pp_addb = "0",
						rm_pp_brightness = "1",
						rm_pp_contrast = "1.2",
						rm_pp_color = "0.95",
						rm_pp_mulr = "1.1",
						rm_pp_mulg = "0.9",
						rm_pp_mulb = "0.9",
						rm_pp_bluralpha = "0.9"
					}
				},
				CVars =
				{
					"rm_pp_addr",
					"rm_pp_addg",
					"rm_pp_addb",
					"rm_pp_brightness",
					"rm_pp_contrast",
					"rm_pp_color",
					"rm_pp_mulr",
					"rm_pp_mulg",
					"rm_pp_mulb",
					"rm_pp_bluralpha"
				},
				MenuButton = "0",
				Folder = ""
			}
		)
		CPanel:AddControl("CheckBox", {Label = "Motion blur", Command = "rm_pp_motionblur_enabled"})
		CPanel:AddControl("CheckBox", {Label = " - Restrict to ragdoll", Command = "rm_pp_motionblur_restrict"})
		CPanel:AddControl("Label", {Text = "\n\nHUD\n"})
		CPanel:AddControl("CheckBox", {Label = "Recovery", Command = "rm_ragdoll_recovery_hud_enabled"})
		CPanel:AddControl("CheckBox", {Label = "Oxygen", Command = "rm_oxygen_hud_enabled"})
		CPanel:AddControl("CheckBox", {Label = " - Text", Command = "rm_oxygen_hud_text_enabled"})
		CPanel:AddControl("CheckBox", {Label = " - Bar", Command = "rm_oxygen_hud_bar_enabled"})
		CPanel:AddControl("CheckBox", {Label = "Afterdeath", Command = "rm_afterdeath_hud_enabled"})
		CPanel:AddControl("CheckBox", {Label = " - Killer", Command = "rm_afterdeath_hud_killer_enabled"})
		CPanel:AddControl("CheckBox", {Label = " - Kills", Command = "rm_afterdeath_hud_kills_enabled"})
		CPanel:AddControl("CheckBox", {Label = " - Respawn time", Command = "rm_afterdeath_hud_respawntime_enabled"})
		CPanel:AddControl("Label", {Text = "\n\nSounds\n"})
		CPanel:AddControl("CheckBox", {Label = "Heartbeat", Command = "rm_sound_heartbeat_enabled"})
		CPanel:AddControl("CheckBox", {Label = "Wind", Command = "rm_sound_wind_enabled"})
		CPanel:AddControl("CheckBox", {Label = " - Restrict to ragdoll", Command = "rm_sound_wind_restrict"})
		CPanel:AddControl("CheckBox", {Label = "Headshot", Command = "rm_headshot_sound_enabled"})
		CPanel:AddControl("Label", {Text = "\n\nAfterdeath\n"})
		CPanel:AddControl("CheckBox", {Label = "Enabled", Command = "rm_afterdeath_client_enabled"})
		CPanel:AddControl("ComboBox",
			{
				Label = "          Camera mode:",
				Options =
				{
					["None"] = {rm_afterdeath_camera_mode = 0},
					["Killer's view"] = {rm_afterdeath_camera_mode = 1},
					["Killer from corpse"] = {rm_afterdeath_camera_mode = 2},
					["Corpse from killer"] = {rm_afterdeath_camera_mode = 3}
				},
				CVars =
				{
					"rm_afterdeath_camera_mode"
				},
				MenuButton = "0",
				Folder = ""
			}
		)
		CPanel:AddControl("Label", {Text = "(Note: Afterdeath also needs to be enabled on the server)"})
		CPanel:AddControl("Label", {Text = "\n\nEffects\n"})
		CPanel:AddControl("CheckBox", {Label = "Headshot killicon", Command = "rm_headshot_client_enabled"})
		CPanel:AddControl("CheckBox", {Label = "Blood spurts", Command = "rm_ragdoll_blood_spurt_enabled"})
		CPanel:AddControl("ComboBox",
			{
				Label = "          - Style:",
				Options =
				{
					["Point"] = {rm_ragdoll_blood_spurt_style = 0},
					["Line"] = {rm_ragdoll_blood_spurt_style = 1},
					["Textured line"] = {rm_ragdoll_blood_spurt_style = 2}
				},
				CVars =
				{
					"rm_ragdoll_blood_spurt_style"
				},
				MenuButton = "0",
				Folder = ""
			}
		)
		CPanel:AddControl("CheckBox", {Label = "Gib chunks", Command = "rm_ragdoll_gib_effect_enabled"})
		CPanel:AddControl("Slider", {Label = "          - Multiplier:", Command = "rm_ragdoll_gib_effect_multiplier", Type = "float", Min = 1, Max = 3})
		CPanel:AddControl("Label", {Text = "\n\n\n\nIf you're having trouble, try reading the help!"})
	end)
end)